FormDisplay.c revision 72f2eca287ec08dcc32adbf1bb6756b5b97b6f34
17c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/** @file
27c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEntry and initialization module for the browser.
37c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
47c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCopyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>
57c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongThis program and the accompanying materials
67c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dongare licensed and made available under the terms and conditions of the BSD License
77c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dongwhich accompanies this distribution.  The full text of the license may be found at
87c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Donghttp://opensource.org/licenses/bsd-license.php
97c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong#include "FormDisplay.h"
167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong//
187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong// Search table for UiDisplayMenu()
197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong//
207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongSCAN_CODE_TO_SCREEN_OPERATION     gScanCodeToOperation[] = {
217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    SCAN_UP,
237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiUp,
247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    SCAN_DOWN,
277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiDown,
287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    SCAN_PAGE_UP,
317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiPageUp,
327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    SCAN_PAGE_DOWN,
357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiPageDown,
367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    SCAN_ESC,
397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiReset,
407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    SCAN_LEFT,
437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiLeft,
447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    SCAN_RIGHT,
477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiRight,
487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong};
507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUINTN mScanCodeNumber = sizeof (gScanCodeToOperation) / sizeof (gScanCodeToOperation[0]);
527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongSCREEN_OPERATION_T0_CONTROL_FLAG  gScreenOperationToControlFlag[] = {
547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiNoOperation,
567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CfUiNoOperation,
577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiSelect,
607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CfUiSelect,
617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiUp,
647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CfUiUp,
657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiDown,
687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CfUiDown,
697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiLeft,
727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CfUiLeft,
737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiRight,
767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CfUiRight,
777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiReset,
807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CfUiReset,
817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiPageUp,
847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CfUiPageUp,
857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiPageDown,
887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CfUiPageDown
897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiHotKey,
927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CfUiHotKey
937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong};
957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFI_GUID  gDisplayEngineGuid = {
977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  0xE38C1029, 0xE38F, 0x45b9, {0x8F, 0x0D, 0xE2, 0xE6, 0x0B, 0xC9, 0xB2, 0x62}
987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong};
997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1005a9f73bf065eda6b830445dc907e778f4a13d8d7Eric DongFORM_ENTRY_INFO               gFormEntryInfo;
1017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUINTN                         gSequence;
1027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFI_SCREEN_DESCRIPTOR         gStatementDimensions;
1037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongBOOLEAN                       mStatementLayoutIsChanged = TRUE;
1047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUSER_INPUT                    *gUserInput;
1057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongFORM_DISPLAY_ENGINE_FORM      *gFormData;
1067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFI_HII_HANDLE                gHiiHandle;
1077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUINT16                        gDirection;
1087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongLIST_ENTRY                    gMenuOption;
1097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongDISPLAY_HIGHLIGHT_MENU_INFO   gHighligthMenuInfo = {0};
1105a9f73bf065eda6b830445dc907e778f4a13d8d7Eric DongBOOLEAN                       mIsFirstForm = TRUE;
1115a9f73bf065eda6b830445dc907e778f4a13d8d7Eric DongFORM_ENTRY_INFO               gOldFormEntry = {0};
1127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong//
1147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong// Browser Global Strings
1157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong//
1167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gFormNotFound;
1177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gNoSubmitIf;
1187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gBrwoserError;
1197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gSaveFailed;
1207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gPromptForData;
1217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gPromptForPassword;
1227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gPromptForNewPassword;
1237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gConfirmPassword;
1247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gConfirmError;
1257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gPassowordInvalid;
1267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gPressEnter;
1277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gEmptyString;
1287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gMiniString;
1297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gOptionMismatch;
1307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gFormSuppress;
1317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gProtocolNotFound;
1327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
133af047db78d297ca33dd74e5e749166bb17a4cc4eEric DongCHAR16            gModalSkipColumn;
1347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            gPromptBlockWidth;
1357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            gOptionBlockWidth;
1367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            gHelpBlockWidth;
1377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *mUnknownString;
1387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongFORM_DISPLAY_DRIVER_PRIVATE_DATA  mPrivateData = {
1407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FORM_DISPLAY_DRIVER_SIGNATURE,
1417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  NULL,
1427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
1437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    FormDisplay,
1445a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong    DriverClearDisplayPage,
1457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ConfirmDataChange
1467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
1477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong};
1487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
1517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Get the string based on the StringId and HII Package List Handle.
1527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Token                  The String's ID.
1547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  HiiHandle              The package list in the HII database to search for
1557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                                 the specified string.
1567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return The output string.
1587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
1607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16 *
1617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongGetToken (
1627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  EFI_STRING_ID                Token,
1637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  EFI_HII_HANDLE               HiiHandle
1647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
1657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
1667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_STRING  String;
1677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  String = HiiGetString (HiiHandle, Token, NULL);
1697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (String == NULL) {
1707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    String = AllocateCopyPool (StrSize (mUnknownString), mUnknownString);
1717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ASSERT (String != NULL);
1727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
1737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return (CHAR16 *) String;
1757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
1767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
1797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Initialize the HII String Token to the correct values.
1807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
1827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
1837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongInitializeDisplayStrings (
1847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  VOID
1857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
1867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
1877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  mUnknownString        = GetToken (STRING_TOKEN (UNKNOWN_STRING), gHiiHandle);
1887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gSaveFailed           = GetToken (STRING_TOKEN (SAVE_FAILED), gHiiHandle);
1897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gPromptForData        = GetToken (STRING_TOKEN (PROMPT_FOR_DATA), gHiiHandle);
1907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gPromptForPassword    = GetToken (STRING_TOKEN (PROMPT_FOR_PASSWORD), gHiiHandle);
1917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gPromptForNewPassword = GetToken (STRING_TOKEN (PROMPT_FOR_NEW_PASSWORD), gHiiHandle);
1927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gConfirmPassword      = GetToken (STRING_TOKEN (CONFIRM_PASSWORD), gHiiHandle);
1937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gConfirmError         = GetToken (STRING_TOKEN (CONFIRM_ERROR), gHiiHandle);
1947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gPassowordInvalid     = GetToken (STRING_TOKEN (PASSWORD_INVALID), gHiiHandle);
1957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gPressEnter           = GetToken (STRING_TOKEN (PRESS_ENTER), gHiiHandle);
1967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gEmptyString          = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
1977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gMiniString           = GetToken (STRING_TOKEN (MINI_STRING), gHiiHandle);
1987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gOptionMismatch       = GetToken (STRING_TOKEN (OPTION_MISMATCH), gHiiHandle);
1997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gFormSuppress         = GetToken (STRING_TOKEN (FORM_SUPPRESSED), gHiiHandle);
2007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gProtocolNotFound     = GetToken (STRING_TOKEN (PROTOCOL_NOT_FOUND), gHiiHandle);
2017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gFormNotFound         = GetToken (STRING_TOKEN (STATUS_BROWSER_FORM_NOT_FOUND), gHiiHandle);
2027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gNoSubmitIf           = GetToken (STRING_TOKEN (STATUS_BROWSER_NO_SUBMIT_IF), gHiiHandle);
2037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gBrwoserError         = GetToken (STRING_TOKEN (STATUS_BROWSER_ERROR), gHiiHandle);
2047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
2057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
2077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Free up the resource allocated for all strings required
2087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  by Setup Browser.
2097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
2117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
2127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongFreeDisplayStrings (
2137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  VOID
2147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
2157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
2167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (mUnknownString);
2177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gEmptyString);
2187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gSaveFailed);
2197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gPromptForData);
2207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gPromptForPassword);
2217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gPromptForNewPassword);
2227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gConfirmPassword);
2237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gConfirmError);
2247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gPassowordInvalid);
2257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gPressEnter);
2267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gMiniString);
2277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gOptionMismatch);
2287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gFormSuppress);
2297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gProtocolNotFound);
2307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gBrwoserError);
2317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gNoSubmitIf);
2327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gFormNotFound);
2337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
2347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
2367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Get prompt string id from the opcode data buffer.
2377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  OpCode                 The input opcode buffer.
2397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return The prompt string id.
2417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
2437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFI_STRING_ID
2447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongGetPrompt (
2457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN EFI_IFR_OP_HEADER     *OpCode
2467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
2477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
2487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_IFR_STATEMENT_HEADER  *Header;
2497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (OpCode->Length <= sizeof (EFI_IFR_OP_HEADER)) {
2517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return 0;
2527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
2537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Header = (EFI_IFR_STATEMENT_HEADER  *) (OpCode + 1);
2557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return Header->Prompt;
2577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
2587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
2607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Get the supported width for a particular op-code
2617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Statement              The curent statement.
263af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  AdjustWidth            The width which is saved for the space.
2647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return Returns the number of CHAR16 characters that is support.
2667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
2687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUINT16
2697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongGetWidth (
270af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN FORM_DISPLAY_ENGINE_STATEMENT        *Statement,
271af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  OUT UINT16                              *AdjustWidth
2727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
2737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
2747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16       *String;
2757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN        Size;
2767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_IFR_TEXT *TestOp;
2777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
278af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
279af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  // For modal form, clean the entire row.
280af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
281af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  if ((gFormData->Attribute & HII_DISPLAY_MODAL) != 0) {
282ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong    if (AdjustWidth  != NULL) {
283ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong      *AdjustWidth = LEFT_SKIPPED_COLUMNS;
284ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong    }
285ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong    return (UINT16)(gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * (gModalSkipColumn + LEFT_SKIPPED_COLUMNS));
286af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  }
287af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Size = 0;
2897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
2917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // See if the second text parameter is really NULL
2927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
2937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) {
2947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    TestOp = (EFI_IFR_TEXT *) Statement->OpCode;
2957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (TestOp->TextTwo != 0) {
2967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      String = GetToken (TestOp->TextTwo, gFormData->HiiHandle);
2977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Size   = StrLen (String);
2987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      FreePool (String);
2997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
3007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
3017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if ((Statement->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) ||
3037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      (Statement->OpCode->OpCode == EFI_IFR_REF_OP) ||
3047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      (Statement->OpCode->OpCode == EFI_IFR_PASSWORD_OP) ||
3057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      (Statement->OpCode->OpCode == EFI_IFR_ACTION_OP) ||
3067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      (Statement->OpCode->OpCode == EFI_IFR_RESET_BUTTON_OP) ||
3077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
3087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Allow a wide display if text op-code and no secondary text op-code
3097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
3107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ((Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) && (Size == 0))
3117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ) {
312af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
313af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    //
314af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    // Return the space width.
315af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    //
316af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    if (AdjustWidth != NULL) {
317af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      *AdjustWidth = 2;
318af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    }
319af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    //
320af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    // Keep consistent with current behavior.
321af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    //
322af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    return (UINT16) (gPromptBlockWidth + gOptionBlockWidth - 2);
3237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
3247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
325af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  if (AdjustWidth != NULL) {
326af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    *AdjustWidth = 1;
327af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  }
328af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  return (UINT16) (gPromptBlockWidth - 1);
3297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
3307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
3327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Will copy LineWidth amount of a string in the OutputString buffer and return the
3337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  number of CHAR16 characters that were copied into the OutputString buffer.
3347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  The output string format is:
3357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Glyph Info + String info + '\0'.
3367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  In the code, it deals \r,\n,\r\n same as \n\r, also it not process the \r or \g.
3387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  InputString            String description for this option.
3407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  LineWidth              Width of the desired string to extract in CHAR16
3417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                                 characters
3427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  GlyphWidth             The glyph width of the begin of the char in the string.
3437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Index                  Where in InputString to start the copy process
3447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  OutputString           Buffer to copy the string into
3457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return Returns the number of CHAR16 characters that were copied into the OutputString
3477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  buffer, include extra glyph info and '\0' info.
3487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
3507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUINT16
3517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongGetLineByWidth (
3527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN      CHAR16                      *InputString,
3537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN      UINT16                      LineWidth,
3547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN OUT  UINT16                      *GlyphWidth,
3557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN OUT  UINTN                       *Index,
3567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OUT     CHAR16                      **OutputString
3577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
3587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
3597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16          StrOffset;
3607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16          GlyphOffset;
3617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16          OriginalGlyphWidth;
3627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BOOLEAN         ReturnFlag;
3637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16          LastSpaceOffset;
3647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16          LastGlyphWidth;
3657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (InputString == NULL || Index == NULL || OutputString == NULL) {
3677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return 0;
3687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
3697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (LineWidth == 0 || *GlyphWidth == 0) {
3717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return 0;
3727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
3737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
3757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Save original glyph width.
3767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
3777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OriginalGlyphWidth = *GlyphWidth;
3787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LastGlyphWidth     = OriginalGlyphWidth;
3797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ReturnFlag         = FALSE;
3807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LastSpaceOffset    = 0;
3817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
3837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // NARROW_CHAR can not be printed in screen, so if a line only contain  the two CHARs: 'NARROW_CHAR + CHAR_CARRIAGE_RETURN' , it is a empty line  in Screen.
3847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // To avoid displaying this  empty line in screen,  just skip  the two CHARs here.
3857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
3867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if ((InputString[*Index] == NARROW_CHAR) && (InputString[*Index + 1] == CHAR_CARRIAGE_RETURN)) {
3877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *Index = *Index + 2;
3887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
3897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
3917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Fast-forward the string and see if there is a carriage-return in the string
3927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
3937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  for (StrOffset = 0, GlyphOffset = 0; GlyphOffset <= LineWidth; StrOffset++) {
3947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    switch (InputString[*Index + StrOffset]) {
3957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case NARROW_CHAR:
3967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        *GlyphWidth = 1;
3977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
3987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case WIDE_CHAR:
4007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        *GlyphWidth = 2;
4017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
4027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case CHAR_CARRIAGE_RETURN:
4047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case CHAR_LINEFEED:
4057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case CHAR_NULL:
4067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ReturnFlag = TRUE;
4077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
4087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      default:
4107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        GlyphOffset = GlyphOffset + *GlyphWidth;
4117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
4137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Record the last space info in this line. Will be used in rewind.
4147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
4157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if ((InputString[*Index + StrOffset] == CHAR_SPACE) && (GlyphOffset <= LineWidth)) {
4167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          LastSpaceOffset = StrOffset;
4177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          LastGlyphWidth  = *GlyphWidth;
4187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
4197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
4207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
4217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (ReturnFlag) {
4237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
4247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
4257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
4267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
4287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Rewind the string from the maximum size until we see a space to break the line
4297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
4307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (GlyphOffset > LineWidth) {
4317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
4327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Rewind the string to last space char in this line.
4337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
4347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (LastSpaceOffset != 0) {
4357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      StrOffset   = LastSpaceOffset;
4367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *GlyphWidth = LastGlyphWidth;
4377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
4387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
4397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Roll back to last char in the line width.
4407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
4417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      StrOffset--;
4427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
4437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
4447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
4467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // The CHAR_NULL has process last time, this time just return 0 to stand for the end.
4477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
4487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (StrOffset == 0 && (InputString[*Index + StrOffset] == CHAR_NULL)) {
4497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return 0;
4507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
4517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
4537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Need extra glyph info and '\0' info, so +2.
4547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
4557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  *OutputString = AllocateZeroPool (((UINTN) (StrOffset + 2) * sizeof(CHAR16)));
4567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (*OutputString == NULL) {
4577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return 0;
4587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
4597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
4617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Save the glyph info at the begin of the string, will used by Print function.
4627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
4637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (OriginalGlyphWidth == 1) {
4647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *(*OutputString) = NARROW_CHAR;
4657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else  {
4667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *(*OutputString) = WIDE_CHAR;
4677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
4687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CopyMem ((*OutputString) + 1, &InputString[*Index], StrOffset * sizeof(CHAR16));
4707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (InputString[*Index + StrOffset] == CHAR_SPACE) {
4727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
4737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Skip the space info at the begin of next line.
4747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
4757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *Index = (UINT16) (*Index + StrOffset + 1);
4767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else if (InputString[*Index + StrOffset] == CHAR_LINEFEED) {
4777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
4787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Skip the /n or /n/r info.
4797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
4807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (InputString[*Index + StrOffset + 1] == CHAR_CARRIAGE_RETURN) {
4817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *Index = (UINT16) (*Index + StrOffset + 2);
4827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
4837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *Index = (UINT16) (*Index + StrOffset + 1);
4847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
4857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else if (InputString[*Index + StrOffset] == CHAR_CARRIAGE_RETURN) {
4867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
4877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Skip the /r or /r/n info.
4887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
4897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (InputString[*Index + StrOffset + 1] == CHAR_LINEFEED) {
4907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *Index = (UINT16) (*Index + StrOffset + 2);
4917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
4927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *Index = (UINT16) (*Index + StrOffset + 1);
4937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
4947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else {
4957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *Index = (UINT16) (*Index + StrOffset);
4967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
4977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
4997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Include extra glyph info and '\0' info, so +2.
5007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
5017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return StrOffset + 2;
5027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
5037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
5057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Add one menu option by specified description and context.
5067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Statement              Statement of this Menu Option.
5087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  MenuItemCount          The index for this Option in the Menu.
5097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  NestIn                 Whether this statement is nest in another statement.
5107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
5127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
5137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUiAddMenuOption (
5147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN FORM_DISPLAY_ENGINE_STATEMENT   *Statement,
5157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN UINT16                          *MenuItemCount,
5167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN BOOLEAN                         NestIn
5177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
5187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
5197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_MENU_OPTION   *MenuOption;
5207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN            Index;
5217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN            Count;
5227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16           *String;
5237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16           NumberOfLines;
5247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16           GlyphWidth;
5257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16           Width;
5267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN            ArrayEntry;
5277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16           *OutputString;
5287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_STRING_ID    PromptId;
5297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  NumberOfLines = 1;
5317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ArrayEntry    = 0;
5327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  GlyphWidth    = 1;
5337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Count         = 1;
5347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  MenuOption    = NULL;
5357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  PromptId = GetPrompt (Statement->OpCode);
5377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT (PromptId != 0);
5387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  String = GetToken (PromptId, gFormData->HiiHandle);
5407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT (String != NULL);
5417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
542af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Width  = GetWidth (Statement, NULL);
5437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  for (; GetLineByWidth (String, Width, &GlyphWidth,&ArrayEntry, &OutputString) != 0x0000;) {
5447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
5457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // If there is more string to process print on the next row and increment the Skip value
5467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
5477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (StrLen (&String[ArrayEntry]) != 0) {
5487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      NumberOfLines++;
5497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
5507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    FreePool (OutputString);
5517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
5527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
5547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
5557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Add three MenuOptions for Date/Time
5567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Data format :      [01/02/2004]      [11:22:33]
5577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Line number :        0  0    1         0  0  1
5587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
5597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    NumberOfLines = 0;
5607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Count = 3;
5617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
5627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  for (Index = 0; Index < Count; Index++) {
5647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    MenuOption = AllocateZeroPool (sizeof (UI_MENU_OPTION));
5657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ASSERT (MenuOption);
5667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    MenuOption->Signature   = UI_MENU_OPTION_SIGNATURE;
5687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    MenuOption->Description = String;
5697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    MenuOption->Handle      = gFormData->HiiHandle;
5707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    MenuOption->ThisTag     = Statement;
5717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    MenuOption->NestInStatement = NestIn;
5727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    MenuOption->EntryNumber = *MenuItemCount;
5737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (Index == 2) {
5757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
5767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Override LineNumber for the MenuOption in Date/Time sequence
5777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
5787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption->Skip = 1;
5797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
5807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption->Skip = NumberOfLines;
5817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
5827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    MenuOption->Sequence = Index;
5837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if ((Statement->Attribute & HII_DISPLAY_GRAYOUT) != 0) {
5857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption->GrayOut = TRUE;
5867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
5877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption->GrayOut = FALSE;
5887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
5897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if ((Statement->Attribute & HII_DISPLAY_LOCK) != 0 || (gFormData->Attribute & HII_DISPLAY_LOCK) != 0) {
5917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption->GrayOut = TRUE;
5927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
5937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
5957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // If the form or the question has the lock attribute, deal same as grayout.
5967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
5977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if ((gFormData->Attribute & HII_DISPLAY_LOCK) != 0 || (Statement->Attribute & HII_DISPLAY_LOCK) != 0) {
5987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption->GrayOut = TRUE;
5997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
6007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    switch (Statement->OpCode->OpCode) {
6027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_ORDERED_LIST_OP:
6037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_ONE_OF_OP:
6047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_NUMERIC_OP:
6057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_TIME_OP:
6067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_DATE_OP:
6077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_CHECKBOX_OP:
6087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_PASSWORD_OP:
6097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_STRING_OP:
6107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
6117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // User could change the value of these items
6127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
6137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption->IsQuestion = TRUE;
6147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
6157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_TEXT_OP:
6167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (FeaturePcdGet (PcdBrowserGrayOutTextStatement)) {
6177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
6187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Initializing GrayOut option as TRUE for Text setup options
6197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // so that those options will be Gray in colour and un selectable.
6207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
6217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        MenuOption->GrayOut = TRUE;
6227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
6237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
6247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    default:
6257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption->IsQuestion = FALSE;
6267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
6277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
6287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if ((Statement->Attribute & HII_DISPLAY_READONLY) != 0) {
6307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption->ReadOnly = TRUE;
6317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (FeaturePcdGet (PcdBrowerGrayOutReadOnlyMenu)) {
6327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        MenuOption->GrayOut = TRUE;
6337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
6347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
6357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    InsertTailList (&gMenuOption, &MenuOption->Link);
6377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
6387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  (*MenuItemCount)++;
6407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
6417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
6437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Create the menu list base on the form data info.
6447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
6467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
6477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongConvertStatementToMenu (
6487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  VOID
6497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
6507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
6517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16                        MenuItemCount;
6527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY                    *Link;
6537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY                    *NestLink;
6547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FORM_DISPLAY_ENGINE_STATEMENT *Statement;
6557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FORM_DISPLAY_ENGINE_STATEMENT *NestStatement;
6567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  MenuItemCount = 0;
6587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  InitializeListHead (&gMenuOption);
6597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Link = GetFirstNode (&gFormData->StatementListHead);
6617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  while (!IsNull (&gFormData->StatementListHead, Link)) {
6627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Statement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);
6637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Link = GetNextNode (&gFormData->StatementListHead, Link);
6647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
6667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Skip the opcode not recognized by Display core.
6677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
6687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (Statement->OpCode->OpCode == EFI_IFR_GUID_OP) {
6697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      continue;
6707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
6717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiAddMenuOption (Statement, &MenuItemCount, FALSE);
6737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
6757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Check the statement nest in this host statement.
6767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
6777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    NestLink = GetFirstNode (&Statement->NestStatementList);
6787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    while (!IsNull (&Statement->NestStatementList, NestLink)) {
6797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      NestStatement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (NestLink);
6807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      NestLink = GetNextNode (&Statement->NestStatementList, NestLink);
6817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      UiAddMenuOption (NestStatement, &MenuItemCount, TRUE);
6837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
6847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
6857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
6867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
6887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Count the storage space of a Unicode string.
6897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  This function handles the Unicode string with NARROW_CHAR
6917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  and WIDE_CHAR control characters. NARROW_HCAR and WIDE_CHAR
6927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  does not count in the resultant output. If a WIDE_CHAR is
6937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  hit, then 2 Unicode character will consume an output storage
6947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  space with size of CHAR16 till a NARROW_CHAR is hit.
6957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  If String is NULL, then ASSERT ().
6977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param String          The input string to be counted.
6997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return Storage space for the input string.
7017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
7037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUINTN
7047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongGetStringWidth (
7057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN CHAR16               *String
7067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
7077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
7087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN Index;
7097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN Count;
7107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN IncrementValue;
7117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT (String != NULL);
7137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (String == NULL) {
7147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return 0;
7157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
7167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Index           = 0;
7187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Count           = 0;
7197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IncrementValue  = 1;
7207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  do {
7227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
7237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Advance to the null-terminator or to the first width directive
7247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
7257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    for (;
7267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong         (String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0);
7277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong         Index++, Count = Count + IncrementValue
7287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        )
7297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ;
7307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
7327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // We hit the null-terminator, we now have a count
7337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
7347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (String[Index] == 0) {
7357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
7367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
7377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
7387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed
7397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2)
7407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
7417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (String[Index] == NARROW_CHAR) {
7427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
7437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Skip to the next character
7447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
7457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Index++;
7467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      IncrementValue = 1;
7477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
7487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
7497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Skip to the next character
7507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
7517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Index++;
7527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      IncrementValue = 2;
7537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
7547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } while (String[Index] != 0);
7557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
7577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Increment by one to include the null-terminator in the size
7587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
7597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Count++;
7607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return Count * sizeof (CHAR16);
7627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
7637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
7657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Base on the input option string to update the skip value for a menu option.
7667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  MenuOption             The MenuOption to be checked.
7687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  OptionString           The input option string.
7697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
7717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
7727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUpdateSkipInfoForMenu (
7737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN UI_MENU_OPTION               *MenuOption,
7747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN CHAR16                       *OptionString
7757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
7767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
7777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN   Index;
7787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16  Width;
7797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN   Row;
7807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16  *OutputString;
7817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16  GlyphWidth;
7827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Width         = (UINT16) gOptionBlockWidth;
7847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  GlyphWidth    = 1;
7857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Row           = 1;
7867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
7887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (StrLen (&OptionString[Index]) != 0) {
7897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Row++;
7907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
7917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    FreePool (OutputString);
7937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
7947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if ((Row > MenuOption->Skip) &&
7967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      (MenuOption->ThisTag->OpCode->OpCode != EFI_IFR_DATE_OP) &&
7977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      (MenuOption->ThisTag->OpCode->OpCode != EFI_IFR_TIME_OP)) {
7987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    MenuOption->Skip = Row;
7997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
8007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
8017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
8037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Update display lines for a Menu Option.
8047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  MenuOption             The MenuOption to be checked.
8067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
8087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
8097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUpdateOptionSkipLines (
8107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN UI_MENU_OPTION               *MenuOption
8117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
8127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
8137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16  *OptionString;
8147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OptionString  = NULL;
8167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ProcessOptions (MenuOption, FALSE, &OptionString, TRUE);
8187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (OptionString != NULL) {
8197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UpdateSkipInfoForMenu (MenuOption, OptionString);
8207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    FreePool (OptionString);
8227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
8237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if ((MenuOption->ThisTag->OpCode->OpCode  == EFI_IFR_TEXT_OP) && (((EFI_IFR_TEXT*)MenuOption->ThisTag->OpCode)->TextTwo != 0)) {
8257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    OptionString   = GetToken (((EFI_IFR_TEXT*)MenuOption->ThisTag->OpCode)->TextTwo, gFormData->HiiHandle);
8267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (OptionString != NULL) {
8287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      UpdateSkipInfoForMenu (MenuOption, OptionString);
8297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      FreePool (OptionString);
8317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
8327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
8337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
8347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
8367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Check whether this Menu Option could be highlighted.
8377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  This is an internal function.
8397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  MenuOption             The MenuOption to be checked.
8417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval TRUE                   This Menu Option is selectable.
8437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval FALSE                  This Menu Option could not be selected.
8447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
8467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongBOOLEAN
8477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongIsSelectable (
8487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_MENU_OPTION   *MenuOption
8497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
8507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
8517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) ||
8527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption->GrayOut || MenuOption->ReadOnly) {
8537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return FALSE;
8547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else {
8557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return TRUE;
8567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
8577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
8587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
8607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Move to next selectable statement.
8617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  This is an internal function.
8637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  GoUp                   The navigation direction. TRUE: up, FALSE: down.
8657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  CurrentPosition        Current position.
8667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  GapToTop               Gap position to top or bottom.
8677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return The row distance from current MenuOption to next selectable MenuOption.
8697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval -1       Reach the begin of the menu, still can't find the selectable menu.
8717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval Value    Find the selectable menu, maybe the truly selectable, maybe the l
8727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                   last menu showing at current form.
8737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
8757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongINTN
8767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongMoveToNextStatement (
8777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN     BOOLEAN                   GoUp,
8787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN OUT LIST_ENTRY                **CurrentPosition,
8797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN     UINTN                     GapToTop
8807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
8817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
8827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  INTN             Distance;
8837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY       *Pos;
8847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_MENU_OPTION   *NextMenuOption;
8857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_MENU_OPTION   *PreMenuOption;
8867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Distance      = 0;
8887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Pos           = *CurrentPosition;
8897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  PreMenuOption = MENU_OPTION_FROM_LINK (Pos);
8907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  while (TRUE) {
8927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    NextMenuOption = MENU_OPTION_FROM_LINK (Pos);
8937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
8947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // NextMenuOption->Row == 0 means this menu has not calculate
8957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // the NextMenuOption->Skip value yet, just calculate here.
8967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
8977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (NextMenuOption->Row == 0) {
8987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      UpdateOptionSkipLines (NextMenuOption);
8997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
9007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (GoUp && (PreMenuOption != NextMenuOption)) {
9027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
9037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // In this case, still can't find the selectable menu,
9047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // return the last one in the showing form.
9057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
9067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {
9077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        NextMenuOption = PreMenuOption;
9087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
9097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
9107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
9127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Current Position doesn't need to be caculated when go up.
9137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Caculate distanct at first when go up
9147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
9157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Distance += NextMenuOption->Skip;
9167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
9177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (IsSelectable (NextMenuOption)) {
9197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
9207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
9217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
9237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Arrive at begin of the menu list.
9247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
9257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if ((GoUp ? Pos->BackLink : Pos->ForwardLink) == &gMenuOption) {
9267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Distance = -1;
9277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
9287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
9297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (!GoUp) {
9317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
9327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // In this case, still can't find the selectable menu,
9337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // return the last one in the showing form.
9347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
9357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {
9367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        NextMenuOption = PreMenuOption;
9377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
9387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
9397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Distance += NextMenuOption->Skip;
9417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
9427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    PreMenuOption = NextMenuOption;
9447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Pos = (GoUp ? Pos->BackLink : Pos->ForwardLink);
9457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
9467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  *CurrentPosition = &NextMenuOption->Link;
9487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return Distance;
9497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
9507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
9537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Process option string for date/time opcode.
9547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  MenuOption              Menu option point to date/time.
9567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  OptionString            Option string input for process.
9577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  AddOptCol               Whether need to update MenuOption->OptCol.
9587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
9607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
9617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongProcessStringForDateTime (
9627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_MENU_OPTION                  *MenuOption,
9637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16                          *OptionString,
9647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BOOLEAN                         AddOptCol
9657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
9667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
9677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN Index;
9687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN Count;
9697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FORM_DISPLAY_ENGINE_STATEMENT          *Statement;
9707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_IFR_DATE                           *Date;
9717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_IFR_TIME                           *Time;
9727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT (MenuOption != NULL && OptionString != NULL);
9747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Statement = MenuOption->ThisTag;
9767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Date      = NULL;
9777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Time      = NULL;
9787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP) {
9797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Date = (EFI_IFR_DATE *) Statement->OpCode;
9807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else if (Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
9817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Time = (EFI_IFR_TIME *) Statement->OpCode;
9827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
9837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
9857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // If leading spaces on OptionString - remove the spaces
9867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
9877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  for (Index = 0; OptionString[Index] == L' '; Index++) {
9887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
9897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Base on the blockspace to get the option column info.
9907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
9917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (AddOptCol) {
9927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption->OptCol++;
9937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
9947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
9957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  for (Count = 0; OptionString[Index] != CHAR_NULL; Index++) {
9977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    OptionString[Count] = OptionString[Index];
9987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Count++;
9997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
10007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OptionString[Count] = CHAR_NULL;
10017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
10037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Enable to suppress field in the opcode base on the flag.
10047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
10057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP) {
10067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
10077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // OptionString format is: <**:  **: ****>
10087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //                        |month|day|year|
10097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //                          4     3    5
10107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
10117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if ((Date->Flags & EFI_QF_DATE_MONTH_SUPPRESS) && (MenuOption->Sequence == 0)) {
10127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
10137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // At this point, only "<**:" in the optionstring.
10147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Clean the day's ** field, after clean, the format is "<  :"
10157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
10167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      SetUnicodeMem (&OptionString[1], 2, L' ');
10177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else if ((Date->Flags & EFI_QF_DATE_DAY_SUPPRESS) && (MenuOption->Sequence == 1)) {
10187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
10197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // At this point, only "**:" in the optionstring.
10207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Clean the month's "**" field, after clean, the format is "  :"
10217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
10227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      SetUnicodeMem (&OptionString[0], 2, L' ');
10237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else if ((Date->Flags & EFI_QF_DATE_YEAR_SUPPRESS) && (MenuOption->Sequence == 2)) {
10247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
10257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // At this point, only "****>" in the optionstring.
10267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Clean the year's "****" field, after clean, the format is "  >"
10277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
10287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      SetUnicodeMem (&OptionString[0], 4, L' ');
10297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
10307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else if (Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
10317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
10327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // OptionString format is: <**:  **:    **>
10337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //                        |hour|minute|second|
10347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //                          4     3      3
10357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
10367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if ((Time->Flags & QF_TIME_HOUR_SUPPRESS) && (MenuOption->Sequence == 0)) {
10377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
10387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // At this point, only "<**:" in the optionstring.
10397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Clean the hour's ** field, after clean, the format is "<  :"
10407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
10417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      SetUnicodeMem (&OptionString[1], 2, L' ');
10427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else if ((Time->Flags & QF_TIME_MINUTE_SUPPRESS) && (MenuOption->Sequence == 1)) {
10437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
10447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // At this point, only "**:" in the optionstring.
10457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Clean the minute's "**" field, after clean, the format is "  :"
10467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
10477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      SetUnicodeMem (&OptionString[0], 2, L' ');
10487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else if ((Time->Flags & QF_TIME_SECOND_SUPPRESS) && (MenuOption->Sequence == 2)) {
10497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
10507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // At this point, only "**>" in the optionstring.
10517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Clean the second's "**" field, after clean, the format is "  >"
10527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
10537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      SetUnicodeMem (&OptionString[0], 2, L' ');
10547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
10557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
10567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
10577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
10607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Adjust Data and Time position accordingly.
10617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Data format :      [01/02/2004]      [11:22:33]
10627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Line number :        0  0    1         0  0  1
10637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  This is an internal function.
10657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  DirectionUp            the up or down direction. False is down. True is
10677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                                 up.
10687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  CurrentPosition        Current position. On return: Point to the last
10697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                                 Option (Year or Second) if up; Point to the first
10707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                                 Option (Month or Hour) if down.
10717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return Return line number to pad. It is possible that we stand on a zero-advance
10737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return data or time opcode, so pad one line when we judge if we are going to scroll outside.
10747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
10767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUINTN
10777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongAdjustDateAndTimePosition (
10787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN     BOOLEAN                     DirectionUp,
10797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN OUT LIST_ENTRY                  **CurrentPosition
10807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
10817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
10827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN           Count;
10837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY      *NewPosition;
10847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_MENU_OPTION  *MenuOption;
10857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN           PadLineNumber;
10867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  PadLineNumber = 0;
10887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  NewPosition   = *CurrentPosition;
10897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  MenuOption    = MENU_OPTION_FROM_LINK (NewPosition);
10907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) ||
10927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)) {
10937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
10947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Calculate the distance from current position to the last Date/Time MenuOption
10957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
10967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Count = 0;
10977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    while (MenuOption->Skip == 0) {
10987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Count++;
10997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      NewPosition   = NewPosition->ForwardLink;
11007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption    = MENU_OPTION_FROM_LINK (NewPosition);
11017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      PadLineNumber = 1;
11027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
11037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    NewPosition = *CurrentPosition;
11057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (DirectionUp) {
11067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
11077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Since the behavior of hitting the up arrow on a Date/Time MenuOption is intended
11087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // to be one that back to the previous set of MenuOptions, we need to advance to the first
11097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Date/Time MenuOption and leave the remaining logic in CfUiUp intact so the appropriate
11107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // checking can be done.
11117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
11127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      while (Count++ < 2) {
11137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        NewPosition = NewPosition->BackLink;
11147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
11157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
11167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
11177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Since the behavior of hitting the down arrow on a Date/Time MenuOption is intended
11187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // to be one that progresses to the next set of MenuOptions, we need to advance to the last
11197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Date/Time MenuOption and leave the remaining logic in CfUiDown intact so the appropriate
11207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // checking can be done.
11217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
11227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      while (Count-- > 0) {
11237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        NewPosition = NewPosition->ForwardLink;
11247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
11257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
11267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *CurrentPosition = NewPosition;
11287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
11297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return PadLineNumber;
11317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
11327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
11347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Get step info from numeric opcode.
11357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param[in] OpCode     The input numeric op code.
11377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return step info for this opcode.
11397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
11407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUINT64
11417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongGetFieldFromNum (
11427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  EFI_IFR_OP_HEADER     *OpCode
11437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
11447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
11457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_IFR_NUMERIC       *NumericOp;
11467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT64                Step;
11477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  NumericOp = (EFI_IFR_NUMERIC *) OpCode;
11497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  switch (NumericOp->Flags & EFI_IFR_NUMERIC_SIZE) {
11517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_NUMERIC_SIZE_1:
11527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Step    = NumericOp->data.u8.Step;
11537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
11547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_NUMERIC_SIZE_2:
11567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Step    = NumericOp->data.u16.Step;
11577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
11587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_NUMERIC_SIZE_4:
11607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Step    = NumericOp->data.u32.Step;
11617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
11627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_NUMERIC_SIZE_8:
11647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Step    = NumericOp->data.u64.Step;
11657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
11667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  default:
11687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Step = 0;
11697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
11707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
11717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return Step;
11737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
11747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
11767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Find the registered HotKey based on KeyData.
11777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param[in] KeyData     A pointer to a buffer that describes the keystroke
11797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                         information for the hot key.
11807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return The registered HotKey context. If no found, NULL will return.
11827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
11837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongBROWSER_HOT_KEY *
11847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongGetHotKeyFromRegisterList (
11857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN EFI_INPUT_KEY *KeyData
11867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
11877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
11887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY       *Link;
11897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BROWSER_HOT_KEY  *HotKey;
11907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Link = GetFirstNode (&gFormData->HotKeyListHead);
11927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  while (!IsNull (&gFormData->HotKeyListHead, Link)) {
11937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);
11947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (HotKey->KeyData->ScanCode == KeyData->ScanCode) {
11967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      return HotKey;
11977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
11987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Link = GetNextNode (&gFormData->HotKeyListHead, Link);
12007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
12017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return NULL;
12037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
12047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
12077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Determine if the menu is the last menu that can be selected.
12087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  This is an internal function.
12107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Direction              The scroll direction. False is down. True is up.
12127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  CurrentPos             The current focus.
12137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return FALSE -- the menu isn't the last menu that can be selected.
12157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return TRUE  -- the menu is the last menu that can be selected.
12167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
12187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongBOOLEAN
12197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongValueIsScroll (
12207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  BOOLEAN                     Direction,
12217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  LIST_ENTRY                  *CurrentPos
12227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
12237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
12247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY      *Temp;
12257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Temp = Direction ? CurrentPos->BackLink : CurrentPos->ForwardLink;
12277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (Temp == &gMenuOption) {
12297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return TRUE;
12307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
12317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return FALSE;
12337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
12347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
12367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Wait for a given event to fire, or for an optional timeout to expire.
12377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Event                  The event to wait for
12397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval UI_EVENT_TYPE          The type of the event which is trigged.
12417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
12437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUI_EVENT_TYPE
12447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUiWaitForEvent (
12457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN EFI_EVENT                Event
12467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
12477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
12487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_STATUS  Status;
12497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN       Index;
12507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN       EventNum;
12517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT64      Timeout;
12527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_EVENT   TimerEvent;
12537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_EVENT   WaitList[3];
12547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_EVENT_TYPE  EventType;
12557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  TimerEvent = NULL;
12577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Timeout    = FormExitTimeout(gFormData);
12587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (Timeout != 0) {
12607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);
12617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
12637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Set the timer event
12647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
12657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    gBS->SetTimer (
12667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          TimerEvent,
12677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          TimerRelative,
12687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Timeout
12697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          );
12707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
12717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  WaitList[0] = Event;
12737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EventNum    = 1;
12747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (gFormData->FormRefreshEvent != NULL) {
12757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    WaitList[EventNum] = gFormData->FormRefreshEvent;
12767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    EventNum ++;
12777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
12787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (Timeout != 0) {
12807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    WaitList[EventNum] = TimerEvent;
12817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    EventNum ++;
12827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
12837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Status = gBS->WaitForEvent (EventNum, WaitList, &Index);
12857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT_EFI_ERROR (Status);
12867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  switch (Index) {
12887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case 0:
12897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong   EventType = UIEventKey;
12907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong   break;
12917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case 1:
12937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (gFormData->FormRefreshEvent != NULL) {
12947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      EventType = UIEventDriver;
12957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
12967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT (Timeout != 0 && EventNum == 2);
12977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      EventType = UIEventTimeOut;
12987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
12997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
13007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  default:
13027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ASSERT (Index == 2 && EventNum == 3);
13037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    EventType = UIEventTimeOut;
13047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
13057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
13067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (Timeout != 0) {
13087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    gBS->CloseEvent (TimerEvent);
13097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
13107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return EventType;
13127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
13137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
13157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Get question id info from the input opcode header.
13167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  OpCode                 The input opcode header pointer.
13187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval                        The question id for this opcode.
13207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
13227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFI_QUESTION_ID
13237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongGetQuestionIdInfo (
13247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN   EFI_IFR_OP_HEADER     *OpCode
13257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
13267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
13277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_IFR_QUESTION_HEADER   *QuestionHeader;
13287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (OpCode->Length < sizeof (EFI_IFR_OP_HEADER) + sizeof (EFI_IFR_QUESTION_HEADER)) {
13307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return 0;
13317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
13327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  QuestionHeader = (EFI_IFR_QUESTION_HEADER *)((UINT8 *) OpCode + sizeof(EFI_IFR_OP_HEADER));
13347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return QuestionHeader->QuestionId;
13367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
13377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
13397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Find the first menu which will be show at the top.
13407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  FormData               The data info for this form.
13427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  TopOfScreen            The link_entry pointer to top menu.
13437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  HighlightMenu          The menu which will be highlight.
13447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  SkipValue              The skip value for the top menu.
13457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
13477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
13487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongFindTopMenu (
13497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  FORM_DISPLAY_ENGINE_FORM  *FormData,
13507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OUT LIST_ENTRY                **TopOfScreen,
13517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OUT LIST_ENTRY                **HighlightMenu,
13527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OUT INTN                      *SkipValue
13537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
13547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
13557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY                      *Link;
13567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY                      *NewPos;
13577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           TopRow;
13587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           BottomRow;
13597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           Index;
13607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_MENU_OPTION                  *SavedMenuOption;
13617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           EndRow;
13627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  TopRow    = gStatementDimensions.TopRow    + SCROLL_ARROW_HEIGHT;
13647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT;
13657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
13677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // If not has input highlight statement, just return the first one in this form.
13687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
13697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (FormData->HighLightedStatement == NULL) {
13707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *TopOfScreen   = gMenuOption.ForwardLink;
13717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *HighlightMenu = gMenuOption.ForwardLink;
13727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (!IsListEmpty (&gMenuOption)) {
13737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow);
13747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
13757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *SkipValue     = 0;
13767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return;
13777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
13787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
13807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Now base on the input highlight menu to find the top menu in this page.
13817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Will base on the highlight menu show at the bottom to find the top menu.
13827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
13837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  NewPos = gMenuOption.ForwardLink;
13847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);
13857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  while ((SavedMenuOption->ThisTag != FormData->HighLightedStatement) ||
13877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong         (SavedMenuOption->Sequence != gSequence)) {
13887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    NewPos     = NewPos->ForwardLink;
13897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (NewPos == &gMenuOption) {
13907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
13917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Not Found it, break
13927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
13937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
13947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
13957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);
13967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
13977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT (SavedMenuOption->ThisTag == FormData->HighLightedStatement);
13987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  *HighlightMenu = NewPos;
14007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  AdjustDateAndTimePosition(FALSE, &NewPos);
14027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);
14037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UpdateOptionSkipLines (SavedMenuOption);
14047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
14067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // If highlight opcode is date/time, keep the highlight row info not change.
14077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
14087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if ((SavedMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP || SavedMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP) &&
14097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      (gHighligthMenuInfo.QuestionId != 0) &&
14107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      (gHighligthMenuInfo.QuestionId == GetQuestionIdInfo(SavedMenuOption->ThisTag->OpCode))) {
14117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
14127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Still show the highlight menu before exit from display engine.
14137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
14147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    EndRow = gHighligthMenuInfo.DisplayRow + SavedMenuOption->Skip;
14157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else {
14167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    EndRow = BottomRow;
14177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
14187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
14207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Base on the selected menu will show at the bottome of next page,
14217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // select the menu show at the top of the next page.
14227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
14237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Link    = NewPos;
14247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  for (Index = TopRow + SavedMenuOption->Skip; Index <= EndRow; ) {
14257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Link = Link->BackLink;
14267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
14277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Already find the first menu in this form, means highlight menu
14287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // will show in first page of this form.
14297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
14307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (Link == &gMenuOption) {
14317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *TopOfScreen   = gMenuOption.ForwardLink;
14327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *SkipValue     = 0;
14337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      return;
14347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
14357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    SavedMenuOption = MENU_OPTION_FROM_LINK (Link);
14367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UpdateOptionSkipLines (SavedMenuOption);
14377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Index += SavedMenuOption->Skip;
14387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
14397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
14417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Found the menu which will show at the top of the page.
14427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
14437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (Link == NewPos) {
14447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
14457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // The menu can show more than one pages, just show the menu at the top of the page.
14467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
14477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *SkipValue    = 0;
14487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *TopOfScreen  = Link;
14497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else {
14507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
14517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Check whether need to skip some line for menu shows at the top of the page.
14527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
14537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *SkipValue = Index - EndRow;
14547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (*SkipValue > 0 && *SkipValue < (INTN) SavedMenuOption->Skip) {
14557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *TopOfScreen     = Link;
14567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
14577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *SkipValue       = 0;
14587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *TopOfScreen     = Link->ForwardLink;
14597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
14607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
14617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
14627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
1464af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Update highlight menu info.
1465af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1466af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  MenuOption               The menu opton which is highlight.
1467af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1468af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong**/
1469af047db78d297ca33dd74e5e749166bb17a4cc4eEric DongVOID
1470af047db78d297ca33dd74e5e749166bb17a4cc4eEric DongUpdateHighlightMenuInfo (
1471af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UI_MENU_OPTION            *MenuOption
1472af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  )
1473af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong{
1474af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  FORM_DISPLAY_ENGINE_STATEMENT   *Statement;
1475af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1476af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
1477af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  // This is the current selected statement
1478af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
1479af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Statement = MenuOption->ThisTag;
1480af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1481af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
1482af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  // Get the highlight statement.
1483af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
1484af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  gUserInput->SelectedStatement = Statement;
1485af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  gSequence = (UINT16) MenuOption->Sequence;
1486af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1487af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
1488af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  // Record highlight row info for date/time opcode.
1489af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
1490af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
1491af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    gHighligthMenuInfo.QuestionId = GetQuestionIdInfo(Statement->OpCode);
1492af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    gHighligthMenuInfo.DisplayRow = (UINT16) MenuOption->Row;
1493af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  } else {
1494af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    gHighligthMenuInfo.QuestionId = 0;
1495af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    gHighligthMenuInfo.DisplayRow = 0;
1496af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  }
1497af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1498af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  RefreshKeyHelp(gFormData, Statement, FALSE);
1499af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong}
1500af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1501af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong/**
1502af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Update attribut for this menu.
1503af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1504af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  MenuOption               The menu opton which this attribut used to.
1505af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  Highlight                Whether this menu will be highlight.
1506af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1507af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong**/
1508af047db78d297ca33dd74e5e749166bb17a4cc4eEric DongVOID
1509af047db78d297ca33dd74e5e749166bb17a4cc4eEric DongSetDisplayAttribute (
1510af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UI_MENU_OPTION                  *MenuOption,
1511af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN BOOLEAN                         Highlight
1512af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  )
1513af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong{
1514af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  FORM_DISPLAY_ENGINE_STATEMENT   *Statement;
1515af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1516af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Statement = MenuOption->ThisTag;
1517af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1518af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  if (Highlight) {
1519af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ());
1520af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    return;
1521af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  }
1522af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1523af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  if (MenuOption->GrayOut) {
1524af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    gST->ConOut->SetAttribute (gST->ConOut, GetGrayedTextColor ());
1525af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  } else {
1526af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    if (Statement->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) {
1527af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      gST->ConOut->SetAttribute (gST->ConOut, GetSubTitleTextColor ());
1528af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    } else {
1529af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
1530af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    }
1531af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  }
1532af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong}
1533af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1534af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong/**
1535af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Print string for this menu option.
1536af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1537af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  MenuOption               The menu opton which this attribut used to.
1538af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  Col                      The column that this string will be print at.
1539af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  Row                      The row that this string will be print at.
1540af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  String                   The string which need to print.
1541af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  Width                    The width need to print, if string is less than the
1542af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong                                   width, the block space will be used.
1543af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  Highlight                Whether this menu will be highlight.
1544af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1545af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong**/
1546af047db78d297ca33dd74e5e749166bb17a4cc4eEric DongVOID
1547af047db78d297ca33dd74e5e749166bb17a4cc4eEric DongDisplayMenuString (
1548af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UI_MENU_OPTION         *MenuOption,
1549af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UINTN                  Col,
1550af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UINTN                  Row,
1551af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN CHAR16                 *String,
1552af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UINTN                  Width,
1553af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN BOOLEAN                Highlight
1554af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  )
1555af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong{
1556af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINTN            Length;
1557af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1558af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
1559af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  // Print string with normal color.
1560af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
1561af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  if (!Highlight) {
1562af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    PrintStringAtWithWidth (Col, Row, String, Width);
1563af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    return;
1564af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  }
1565af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1566af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
1567af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  // Print the highlight menu string.
1568af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  // First print the highlight string.
1569af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
1570af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  SetDisplayAttribute(MenuOption, TRUE);
1571af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Length = PrintStringAt (Col, Row, String);
1572af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1573af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
1574af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  // Second, clean the empty after the string.
1575af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
1576af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  SetDisplayAttribute(MenuOption, FALSE);
1577af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  PrintStringAtWithWidth (Col + Length, Row, L"", Width - Length);
1578af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong}
1579af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1580af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong/**
158128401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  Check whether this menu can has option string.
158228401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
158328401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  @param  MenuOption               The menu opton which this attribut used to.
158428401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
158528401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  @retval TRUE                     This menu option can have option string.
158628401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  @retval FALSE                    This menu option can't have option string.
158728401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
158828401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong**/
158928401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric DongBOOLEAN
159028401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric DongHasOptionString (
159128401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  IN UI_MENU_OPTION                  *MenuOption
159228401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  )
159328401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong{
159428401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  FORM_DISPLAY_ENGINE_STATEMENT   *Statement;
159528401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  CHAR16                          *String;
159628401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  UINTN                           Size;
159728401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  EFI_IFR_TEXT                    *TestOp;
159828401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
159928401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  Size = 0;
160028401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  Statement = MenuOption->ThisTag;
160128401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
160228401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  //
160328401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  // See if the second text parameter is really NULL
160428401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  //
160528401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  if (Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) {
160628401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    TestOp = (EFI_IFR_TEXT *) Statement->OpCode;
160728401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    if (TestOp->TextTwo != 0) {
160828401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong      String = GetToken (TestOp->TextTwo, gFormData->HiiHandle);
160928401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong      Size   = StrLen (String);
161028401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong      FreePool (String);
161128401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    }
161228401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  }
161328401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
161428401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  if ((Statement->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) ||
161528401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    (Statement->OpCode->OpCode == EFI_IFR_REF_OP) ||
161628401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    (Statement->OpCode->OpCode == EFI_IFR_PASSWORD_OP) ||
161728401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    (Statement->OpCode->OpCode == EFI_IFR_ACTION_OP) ||
161828401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    (Statement->OpCode->OpCode == EFI_IFR_RESET_BUTTON_OP) ||
161928401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    //
162028401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    // Allow a wide display if text op-code and no secondary text op-code
162128401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    //
162228401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    ((Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) && (Size == 0))
162328401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    ) {
162428401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
162528401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    return FALSE;
162628401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  }
162728401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
162828401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  return TRUE;
162928401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong}
163028401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
163128401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
163228401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong/**
1633af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Print string for this menu option.
1634af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1635af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  MenuOption               The menu opton which this attribut used to.
1636af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  SkipWidth                The skip width between the left to the start of the prompt.
1637af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  BeginCol                 The begin column for one menu.
1638af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  SkipLine                 The skip line for this menu.
1639af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  BottomRow                The bottom row for this form.
1640af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  Highlight                Whether this menu will be highlight.
1641af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1642af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @retval EFI_SUCESSS              Process the user selection success.
1643af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1644af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong**/
1645af047db78d297ca33dd74e5e749166bb17a4cc4eEric DongEFI_STATUS
1646af047db78d297ca33dd74e5e749166bb17a4cc4eEric DongDisplayOneMenu (
1647af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UI_MENU_OPTION                  *MenuOption,
1648af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UINTN                           SkipWidth,
1649af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UINTN                           BeginCol,
1650af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UINTN                           SkipLine,
1651af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UINTN                           BottomRow,
1652af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN BOOLEAN                         Highlight
1653af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  )
1654af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong{
1655af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  FORM_DISPLAY_ENGINE_STATEMENT   *Statement;
1656af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINTN                           Index;
1657af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINT16                          Width;
1658af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINT16                          PromptWidth;
1659af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  CHAR16                          *StringPtr;
1660af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  CHAR16                          *OptionString;
1661af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  CHAR16                          *OutputString;
1662af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINT16                          GlyphWidth;
1663af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINTN                           Temp;
1664af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINTN                           Temp2;
1665af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINTN                           Temp3;
1666af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  EFI_STATUS                      Status;
1667af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINTN                           Row;
1668af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINTN                           Col;
1669af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINTN                           PromptLineNum;
167028401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  UINTN                           OptionLineNum;
1671af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  CHAR16                          AdjustValue;
167228401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  UINTN                           MaxRow;
1673af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1674af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Statement = MenuOption->ThisTag;
1675af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Temp      = SkipLine;
1676af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Temp2     = SkipLine;
1677af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Temp3     = SkipLine;
167828401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  AdjustValue   = 0;
167928401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  PromptLineNum = 0;
168028401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  OptionLineNum = 0;
168128401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  MaxRow        = 0;
1682af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1683af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
1684af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  // Set default color.
1685af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
1686af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  SetDisplayAttribute (MenuOption, FALSE);
1687af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1688af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
1689af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  // 1. Paint the option string.
1690af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
1691af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Status = ProcessOptions (MenuOption, FALSE, &OptionString, FALSE);
1692af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  if (EFI_ERROR (Status)) {
1693af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    return Status;
1694af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  }
1695af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1696af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  if (OptionString != NULL) {
1697af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
1698af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      //
1699af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      // Adjust option string for date/time opcode.
1700af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      //
1701af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      ProcessStringForDateTime(MenuOption, OptionString, TRUE);
1702af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    }
1703af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1704af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    Width       = (UINT16) gOptionBlockWidth - 1;
170528401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    Row         = MenuOption->Row;
1706af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    GlyphWidth  = 1;
170728401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    OptionLineNum = 0;
1708af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1709af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
1710af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if (((Temp2 == 0)) && (Row <= BottomRow)) {
1711af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
1712af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          //
1713af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          // For date/time question, it has three menu options for this qustion.
1714af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          // The first/second menu options with the skip value is 0. the last one
1715af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          // with skip value is 1.
1716af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          //
1717af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          if (MenuOption->Skip != 0) {
1718af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            //
1719af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            // For date/ time, print the last past (year for date and second for time)
1720af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            // - 7 means skip [##/##/ for date and [##:##: for time.
1721af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            //
1722af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            DisplayMenuString (MenuOption,MenuOption->OptCol, Row, OutputString, Width + 1 - 7, Highlight);
1723af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          } else {
1724af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            //
1725af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            // For date/ time, print the first and second past (year for date and second for time)
1726af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            //
1727af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, StrLen (OutputString), Highlight);
1728af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          }
1729af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        } else {
1730af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, Width + 1, Highlight);
1731af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        }
173228401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong        OptionLineNum++;
1733af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      }
1734af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1735af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      //
1736af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      // If there is more string to process print on the next row and increment the Skip value
1737af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      //
1738af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if (StrLen (&OptionString[Index]) != 0) {
1739af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        if (Temp2 == 0) {
1740af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          Row++;
1741af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          //
1742af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          // Since the Number of lines for this menu entry may or may not be reflected accurately
1743af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          // since the prompt might be 1 lines and option might be many, and vice versa, we need to do
1744af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          // some testing to ensure we are keeping this in-sync.
1745af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          //
1746af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          // If the difference in rows is greater than or equal to the skip value, increase the skip value
1747af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          //
174828401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong          if ((Row - MenuOption->Row) >= MenuOption->Skip) {
1749af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            MenuOption->Skip++;
1750af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          }
1751af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        }
1752af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      }
1753af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1754af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      FreePool (OutputString);
1755af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if (Temp2 != 0) {
1756af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        Temp2--;
1757af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      }
1758af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    }
1759af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1760af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    Highlight = FALSE;
1761af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1762af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    FreePool (OptionString);
1763af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  }
1764af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1765af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
176628401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  // 2. Paint the description.
1767af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
1768af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  PromptWidth   = GetWidth (Statement, &AdjustValue);
176928401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  Row           = MenuOption->Row;
1770af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  GlyphWidth    = 1;
1771af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  PromptLineNum = 0;
1772af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1773af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  if (MenuOption->Description == NULL || MenuOption->Description[0] == '\0') {
177428401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    PrintStringAtWithWidth (BeginCol, Row, L"", PromptWidth + AdjustValue + SkipWidth);
177528401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    PromptLineNum++;
1776af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  } else {
1777af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    for (Index = 0; GetLineByWidth (MenuOption->Description, PromptWidth, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
1778af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if ((Temp == 0) && (Row <= BottomRow)) {
1779af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        //
1780af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        // 1.Clean the start LEFT_SKIPPED_COLUMNS
1781af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        //
1782af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        PrintStringAtWithWidth (BeginCol, Row, L"", SkipWidth);
1783af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1784af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        if (Statement->OpCode->OpCode == EFI_IFR_REF_OP && MenuOption->Col >= 2) {
1785af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          //
1786af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          // Print Arrow for Goto button.
1787af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          //
1788af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          PrintCharAt (
1789af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            MenuOption->Col - 2,
1790af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            Row,
1791af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            GEOMETRICSHAPE_RIGHT_TRIANGLE
1792af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            );
1793af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        }
1794af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        DisplayMenuString (MenuOption, MenuOption->Col, Row, OutputString, PromptWidth + AdjustValue, Highlight);
1795af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        PromptLineNum ++;
1796af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      }
1797af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      //
1798af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      // If there is more string to process print on the next row and increment the Skip value
1799af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      //
1800af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if (StrLen (&MenuOption->Description[Index]) != 0) {
1801af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        if (Temp == 0) {
1802af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          Row++;
1803af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        }
1804af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      }
1805af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1806af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      FreePool (OutputString);
1807af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if (Temp != 0) {
1808af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        Temp--;
1809af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      }
1810af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    }
1811af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1812af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    Highlight = FALSE;
1813af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  }
1814af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1815af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1816af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
181728401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  // 3. If this is a text op with secondary text information
1818af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
1819af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  if ((Statement->OpCode->OpCode  == EFI_IFR_TEXT_OP) && (((EFI_IFR_TEXT*)Statement->OpCode)->TextTwo != 0)) {
1820af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    StringPtr   = GetToken (((EFI_IFR_TEXT*)Statement->OpCode)->TextTwo, gFormData->HiiHandle);
1821af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1822af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    Width       = (UINT16) gOptionBlockWidth - 1;
182328401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    Row         = MenuOption->Row;
1824af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    GlyphWidth  = 1;
182528401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    OptionLineNum = 0;
1826af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1827af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    for (Index = 0; GetLineByWidth (StringPtr, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
1828af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if ((Temp3 == 0) && (Row <= BottomRow)) {
1829af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, Width + 1, Highlight);
183028401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong        OptionLineNum++;
1831af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      }
1832af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      //
1833af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      // If there is more string to process print on the next row and increment the Skip value
1834af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      //
1835af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if (StrLen (&StringPtr[Index]) != 0) {
1836af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        if (Temp3 == 0) {
1837af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          Row++;
1838af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        }
1839af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      }
1840af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1841af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      FreePool (OutputString);
1842af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if (Temp3 != 0) {
1843af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        Temp3--;
1844af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      }
1845af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    }
184628401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
1847af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    FreePool (StringPtr);
1848af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  }
1849af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
185028401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  //
185128401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  // 4.Line number for Option string and prompt string are not equal.
185228401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  //  Clean the column whose line number is less.
185328401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  //
185428401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  if (HasOptionString(MenuOption) && (OptionLineNum != PromptLineNum)) {
185528401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    Col    =  OptionLineNum < PromptLineNum ? MenuOption->OptCol : BeginCol;
185628401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    Row    = (OptionLineNum < PromptLineNum ? OptionLineNum : PromptLineNum) + MenuOption->Row;
185728401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    Width  = (UINT16) (OptionLineNum < PromptLineNum ? gOptionBlockWidth : PromptWidth + AdjustValue + SkipWidth);
185828401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    MaxRow = (OptionLineNum < PromptLineNum ? PromptLineNum : OptionLineNum) + MenuOption->Row - 1;
185928401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
186028401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    while (Row <= MaxRow) {
186128401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong      DisplayMenuString (MenuOption, Col, Row++, L"", Width, FALSE);
186228401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    }
186328401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  }
186428401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
1865af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  return EFI_SUCCESS;
1866af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong}
1867af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1868af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong/**
18697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Display menu and wait for user to select one menu option, then return it.
18707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  If AutoBoot is enabled, then if user doesn't select any option,
18717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  after period of time, it will automatically return the first menu option.
18727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
18737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  FormData               The current form data info.
18747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
18757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval EFI_SUCESSS            Process the user selection success.
18767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval EFI_NOT_FOUND          Process option string for orderedlist/Oneof fail.
18777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
18787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
18797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFI_STATUS
18807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUiDisplayMenu (
18817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  FORM_DISPLAY_ENGINE_FORM  *FormData
18827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
18837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
18847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  INTN                            SkipValue;
18857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  INTN                            Difference;
18867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           DistanceValue;
18877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           Row;
18887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           Col;
18897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           Temp;
18907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           Temp2;
18917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           TopRow;
18927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           BottomRow;
18937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           OriginalRow;
18947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           Index;
18957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16                          Width;
18967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16                          *StringPtr;
18977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16                          *OptionString;
18987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16                          *OutputString;
18997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16                          *HelpString;
19007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16                          *HelpHeaderString;
19017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16                          *HelpBottomString;
19027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BOOLEAN                         NewLine;
19037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BOOLEAN                         Repaint;
19047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BOOLEAN                         UpArrow;
19057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BOOLEAN                         DownArrow;
19067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_STATUS                      Status;
19077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_INPUT_KEY                   Key;
19087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY                      *Link;
19097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY                      *NewPos;
19107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY                      *TopOfScreen;
19117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY                      *SavedListEntry;
19127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_MENU_OPTION                  *MenuOption;
19137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_MENU_OPTION                  *NextMenuOption;
19147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_MENU_OPTION                  *SavedMenuOption;
19157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_MENU_OPTION                  *PreviousMenuOption;
19167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_CONTROL_FLAG                 ControlFlag;
19177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_SCREEN_OPERATION             ScreenOperation;
19187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16                          DefaultId;
19197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FORM_DISPLAY_ENGINE_STATEMENT   *Statement;
19207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BROWSER_HOT_KEY                 *HotKey;
19217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           HelpPageIndex;
19227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           HelpPageCount;
19237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           RowCount;
19247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           HelpLine;
19257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           HelpHeaderLine;
19267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           HelpBottomLine;
19277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BOOLEAN                         MultiHelpPage;
19287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16                          GlyphWidth;
19297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16                          EachLineWidth;
19307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16                          HeaderLineWidth;
19317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16                          BottomLineWidth;
19327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_STRING_ID                   HelpInfo;
19337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_EVENT_TYPE                   EventType;
19347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FORM_DISPLAY_ENGINE_STATEMENT   *InitialHighlight;
1935af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  BOOLEAN                         SkipHighLight;
19367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
19377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EventType           = UIEventNone;
19387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Status              = EFI_SUCCESS;
19397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HelpString          = NULL;
19407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HelpHeaderString    = NULL;
19417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HelpBottomString    = NULL;
19427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OptionString        = NULL;
19437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ScreenOperation     = UiNoOperation;
19447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  NewLine             = TRUE;
19457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  DefaultId           = 0;
19467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HelpPageCount       = 0;
19477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HelpLine            = 0;
19487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  RowCount            = 0;
19497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HelpBottomLine      = 0;
19507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HelpHeaderLine      = 0;
19517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HelpPageIndex       = 0;
19527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  MultiHelpPage       = FALSE;
19537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EachLineWidth       = 0;
19547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HeaderLineWidth     = 0;
19557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BottomLineWidth     = 0;
19567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OutputString        = NULL;
19577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UpArrow             = FALSE;
19587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  DownArrow           = FALSE;
19597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  SkipValue           = 0;
1960af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  SkipHighLight       = FALSE;
19617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
19627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  NextMenuOption      = NULL;
19637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  PreviousMenuOption  = NULL;
19647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  SavedMenuOption     = NULL;
19657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HotKey              = NULL;
19667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Repaint             = TRUE;
19677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  MenuOption          = NULL;
1968af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  gModalSkipColumn    = (CHAR16) (gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 6;
19697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  InitialHighlight    = gFormData->HighLightedStatement;
19707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
19717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ZeroMem (&Key, sizeof (EFI_INPUT_KEY));
19727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1973af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
1974af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //  Left                                              right
1975af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //   |<-.->|<-.........->|<- .........->|<-...........->|
1976af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //     Skip    Prompt         Option         Help
1977af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
1978af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Width             = (CHAR16) ((gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 3);
1979af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  gOptionBlockWidth = Width + 1;
1980af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  gHelpBlockWidth   = (CHAR16) (Width - LEFT_SKIPPED_COLUMNS);
1981af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  gPromptBlockWidth = (CHAR16) (gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * Width - 1);
19827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
19837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  TopRow    = gStatementDimensions.TopRow    + SCROLL_ARROW_HEIGHT;
19847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT - 1;
19857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
19867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Row = TopRow;
19877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
1988af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    Col = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS + gModalSkipColumn;
19897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else {
19907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Col = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS;
19917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
19927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
19937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FindTopMenu(FormData, &TopOfScreen, &NewPos, &SkipValue);
19947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
19957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gST->ConOut->EnableCursor (gST->ConOut, FALSE);
19967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
19977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ControlFlag = CfInitialization;
19987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  while (TRUE) {
19997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    switch (ControlFlag) {
20007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfInitialization:
2001af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if ((gOldFormEntry.HiiHandle != FormData->HiiHandle) ||
2002af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          (!CompareGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid))) {
2003af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        //
2004af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        // Clear Statement range if different formset is painted.
2005af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        //
2006af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        ClearLines (
2007af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          gStatementDimensions.LeftColumn,
2008af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          gStatementDimensions.RightColumn,
2009af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          TopRow - SCROLL_ARROW_HEIGHT,
2010af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          BottomRow + SCROLL_ARROW_HEIGHT,
2011af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          GetFieldTextColor ()
2012af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          );
20137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
20147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
2015af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      ControlFlag = CfRepaint;
20167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
20177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
20187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfRepaint:
20197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfRefreshHighLight;
20207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
20217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (Repaint) {
20227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
20237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Display menu
20247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
20257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        DownArrow       = FALSE;
20267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        UpArrow         = FALSE;
20277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Row             = TopRow;
20287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2029af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
2030af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
20317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
2032af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        // 1. Check whether need to print the arrow up.
20337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
2034af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        if (!ValueIsScroll (TRUE, TopOfScreen)) {
2035af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          UpArrow = TRUE;
2036af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        }
2037af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2038ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong        if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
2039ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong          PrintStringAtWithWidth(gStatementDimensions.LeftColumn + gModalSkipColumn, TopRow - 1, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * gModalSkipColumn);
2040ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong        } else {
2041ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong          PrintStringAtWithWidth(gStatementDimensions.LeftColumn, TopRow - 1, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn);
2042ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong        }
2043af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        if (UpArrow) {
2044af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          gST->ConOut->SetAttribute (gST->ConOut, GetArrowColor ());
2045af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          PrintCharAt (
2046af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            gStatementDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,
20477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            TopRow - SCROLL_ARROW_HEIGHT,
2048af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            ARROW_UP
20497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            );
2050af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
20517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
20527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
20537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
20547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // 2.Paint the menu.
20557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
20567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        for (Link = TopOfScreen; Link != &gMenuOption; Link = Link->ForwardLink) {
20577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          MenuOption          = MENU_OPTION_FROM_LINK (Link);
20587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          MenuOption->Row     = Row;
20597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          MenuOption->Col     = Col;
20607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
2061af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            MenuOption->OptCol  = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS + gPromptBlockWidth + gModalSkipColumn;
20627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          } else {
2063af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            MenuOption->OptCol  = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS + gPromptBlockWidth;
20647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
20657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
20667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (MenuOption->NestInStatement) {
20677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            MenuOption->Col += SUBTITLE_INDENT;
20687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
20697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
20707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
2071af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          // Save the highlight menu, will be used in CfRefreshHighLight case.
20727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
2073af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          if (Link == NewPos) {
2074af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            SavedMenuOption = MenuOption;
2075af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            SkipHighLight   = TRUE;
20767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
2077ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong
2078ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong          if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
207972f2eca287ec08dcc32adbf1bb6756b5b97b6f34Eric Dong            Status = DisplayOneMenu (MenuOption,
2080ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong                            LEFT_SKIPPED_COLUMNS,
2081ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong                            gStatementDimensions.LeftColumn + gModalSkipColumn,
2082ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong                            Link == TopOfScreen ? SkipValue : 0,
2083ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong                            BottomRow,
2084571c73b5a43c50218ffa3b927f6e3a6fb9ba5e68Eric Dong                            (BOOLEAN) ((Link == NewPos) && IsSelectable(MenuOption))
2085ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong                            );
2086ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong          } else {
208772f2eca287ec08dcc32adbf1bb6756b5b97b6f34Eric Dong            Status = DisplayOneMenu (MenuOption,
2088ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong                            LEFT_SKIPPED_COLUMNS,
2089ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong                            gStatementDimensions.LeftColumn,
2090ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong                            Link == TopOfScreen ? SkipValue : 0,
2091ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong                            BottomRow,
2092571c73b5a43c50218ffa3b927f6e3a6fb9ba5e68Eric Dong                            (BOOLEAN) ((Link == NewPos) && IsSelectable(MenuOption))
2093ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong                            );
2094ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong          }
20957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
209672f2eca287ec08dcc32adbf1bb6756b5b97b6f34Eric Dong          if (EFI_ERROR (Status)) {
209772f2eca287ec08dcc32adbf1bb6756b5b97b6f34Eric Dong            return Status;
209872f2eca287ec08dcc32adbf1bb6756b5b97b6f34Eric Dong          }
20997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
21007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // 3. Update the row info which will be used by next menu.
21017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
21027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (Link == TopOfScreen) {
21037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Row += MenuOption->Skip - SkipValue;
21047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          } else {
21057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Row += MenuOption->Skip;
21067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
21077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
21087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (Row > BottomRow) {
21097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            if (!ValueIsScroll (FALSE, Link)) {
21107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              DownArrow = TRUE;
21117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            }
21127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
21137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Row = BottomRow + 1;
21147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            break;
21157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
21167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
21177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2118af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        //
2119af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        // 3. Menus in this form may not cover all form, clean the remain field.
2120af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        //
2121af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        while (Row <= BottomRow) {
2122af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
2123ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong            PrintStringAtWithWidth(gStatementDimensions.LeftColumn + gModalSkipColumn, Row++, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * gModalSkipColumn);
2124af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          } else {
2125af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            PrintStringAtWithWidth(gStatementDimensions.LeftColumn, Row++, L"", gStatementDimensions.RightColumn - gHelpBlockWidth - gStatementDimensions.LeftColumn);
2126af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          }
21277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
21287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2129af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        //
2130af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        // 4. Print the down arrow row.
2131af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        //
2132ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong        if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
2133ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong          PrintStringAtWithWidth(gStatementDimensions.LeftColumn + gModalSkipColumn, BottomRow + 1, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 *  + gModalSkipColumn);
2134ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong        } else {
2135ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong          PrintStringAtWithWidth(gStatementDimensions.LeftColumn, BottomRow + 1, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn);
2136ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong        }
21377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (DownArrow) {
21387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          gST->ConOut->SetAttribute (gST->ConOut, GetArrowColor ());
21397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          PrintCharAt (
21407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gStatementDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,
21417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            BottomRow + SCROLL_ARROW_HEIGHT,
21427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            ARROW_DOWN
21437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            );
21447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
21457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
21467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
21477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        MenuOption = NULL;
2148af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2149af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        if (IsListEmpty (&gMenuOption)) {
2150af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          ControlFlag = CfReadKey;
2151af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        }
21527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
21537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
21547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
21557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfRefreshHighLight:
21567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
21577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
21587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // MenuOption: Last menu option that need to remove hilight
21597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //             MenuOption is set to NULL in Repaint
21607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // NewPos:     Current menu option that need to hilight
21617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
21627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfUpdateHelpString;
21637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2164af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if (SkipHighLight) {
2165af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        MenuOption    = SavedMenuOption;
2166af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        SkipHighLight = FALSE;
2167af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        UpdateHighlightMenuInfo (MenuOption);
2168af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        break;
2169af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      }
2170af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
21717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (MenuOption != NULL && TopOfScreen == &MenuOption->Link) {
21727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Temp = SkipValue;
21737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      } else {
21747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Temp = 0;
21757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
21767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (NewPos == TopOfScreen) {
21777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Temp2 = SkipValue;
21787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      } else {
21797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Temp2 = 0;
21807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
21817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
21827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (NewPos != NULL && (MenuOption == NULL || NewPos != &MenuOption->Link)) {
21837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (MenuOption != NULL) {
21847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
21857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Remove highlight on last Menu Option
21867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
21877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);
21887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ProcessOptions (MenuOption, FALSE, &OptionString, TRUE);
21897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
21907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (OptionString != NULL) {
21917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) ||
21927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)
21937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong               ) {
21947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              ProcessStringForDateTime(MenuOption, OptionString, FALSE);
21957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            }
21967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
21977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Width               = (UINT16) gOptionBlockWidth;
21987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            OriginalRow         = MenuOption->Row;
21997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            GlyphWidth          = 1;
22007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
22017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
22027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {
22037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);
22047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              }
22057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              //
22067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              // If there is more string to process print on the next row and increment the Skip value
22077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              //
22087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              if (StrLen (&OptionString[Index]) != 0) {
22097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                if (Temp == 0) {
22107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  MenuOption->Row++;
22117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                }
22127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              }
22137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
22147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              FreePool (OutputString);
22157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              if (Temp != 0) {
22167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                Temp--;
22177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              }
22187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            }
22197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
22207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            MenuOption->Row = OriginalRow;
22217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
22227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            FreePool (OptionString);
22237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          } else {
22247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            if (NewLine) {
22257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              if (MenuOption->GrayOut) {
22267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                gST->ConOut->SetAttribute (gST->ConOut, GetGrayedTextColor ());
22277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              } else if (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) {
22287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                gST->ConOut->SetAttribute (gST->ConOut, GetSubTitleTextColor ());
22297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              }
22307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
22317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              OriginalRow = MenuOption->Row;
2232af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong              Width       = GetWidth (MenuOption->ThisTag, NULL);
22337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              GlyphWidth  = 1;
22347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
22357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
22367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {
22377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);
22387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                }
22397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                //
22407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                // If there is more string to process print on the next row and increment the Skip value
22417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                //
22427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                if (StrLen (&MenuOption->Description[Index]) != 0) {
22437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  if (Temp == 0) {
22447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                    MenuOption->Row++;
22457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  }
22467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                }
22477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
22487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                FreePool (OutputString);
22497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                if (Temp != 0) {
22507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  Temp--;
22517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                }
22527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              }
22537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
22547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              MenuOption->Row = OriginalRow;
22557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
22567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            }
22577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
22587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
22597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
22607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
22617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // This is the current selected statement
22627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
22637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        MenuOption = MENU_OPTION_FROM_LINK (NewPos);
22647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Statement = MenuOption->ThisTag;
22657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2266af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        UpdateHighlightMenuInfo (MenuOption);
22677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
22687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (!IsSelectable (MenuOption)) {
22697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
22707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
22717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
22727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
22737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Set reverse attribute
22747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
22757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ());
22767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);
22777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
22787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ProcessOptions (MenuOption, FALSE, &OptionString, TRUE);
22797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (OptionString != NULL) {
22807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
22817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            ProcessStringForDateTime(MenuOption, OptionString, FALSE);
22827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
22837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Width               = (UINT16) gOptionBlockWidth;
22847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
22857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          OriginalRow         = MenuOption->Row;
22867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          GlyphWidth          = 1;
22877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
22887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
22897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {
22907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);
22917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            }
22927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
22937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            // If there is more string to process print on the next row and increment the Skip value
22947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
22957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            if (StrLen (&OptionString[Index]) != 0) {
22967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              if (Temp2 == 0) {
22977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              MenuOption->Row++;
22987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              }
22997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            }
23007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
23017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            FreePool (OutputString);
23027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            if (Temp2 != 0) {
23037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              Temp2--;
23047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            }
23057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
23067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
23077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          MenuOption->Row = OriginalRow;
23087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
23097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          FreePool (OptionString);
23107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else {
23117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (NewLine) {
23127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            OriginalRow = MenuOption->Row;
23137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2314af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            Width       = GetWidth (Statement, NULL);
23157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            GlyphWidth          = 1;
23167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
23177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
23187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {
23197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);
23207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              }
23217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              //
23227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              // If there is more string to process print on the next row and increment the Skip value
23237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              //
23247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              if (StrLen (&MenuOption->Description[Index]) != 0) {
23257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                if (Temp2 == 0) {
23267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  MenuOption->Row++;
23277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                }
23287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              }
23297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
23307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              FreePool (OutputString);
23317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              if (Temp2 != 0) {
23327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                Temp2--;
23337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              }
23347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            }
23357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
23367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            MenuOption->Row = OriginalRow;
23377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
23387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
23397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
23407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
23417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
23427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Clear reverse attribute
23437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
23447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
23457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
23467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
23477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
23487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUpdateHelpString:
23497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfPrepareToReadKey;
23507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
23517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
23527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
23537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
23547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (Repaint || NewLine) {
23557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
23567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Don't print anything if it is a NULL help token
23577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
23587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ASSERT(MenuOption != NULL);
23597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        HelpInfo = ((EFI_IFR_STATEMENT_HEADER *) ((CHAR8 *)MenuOption->ThisTag->OpCode + sizeof (EFI_IFR_OP_HEADER)))->Help;
23607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (HelpInfo == 0 || !IsSelectable (MenuOption)) {
23617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          StringPtr = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
23627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else {
23637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          StringPtr = GetToken (HelpInfo, gFormData->HiiHandle);
23647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
23657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
23667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        RowCount      = BottomRow - TopRow + 1;
23677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        HelpPageIndex = 0;
23687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
23697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // 1.Calculate how many line the help string need to print.
23707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
23717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (HelpString != NULL) {
23727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          FreePool (HelpString);
23737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          HelpString = NULL;
23747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
23757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        HelpLine = ProcessHelpString (StringPtr, &HelpString, &EachLineWidth, RowCount);
23767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        FreePool (StringPtr);
23777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
23787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (HelpLine > RowCount) {
23797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          MultiHelpPage   = TRUE;
23807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          StringPtr       = GetToken (STRING_TOKEN(ADJUST_HELP_PAGE_UP), gHiiHandle);
23817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (HelpHeaderString != NULL) {
23827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            FreePool (HelpHeaderString);
23837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            HelpHeaderString = NULL;
23847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
23857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          HelpHeaderLine  = ProcessHelpString (StringPtr, &HelpHeaderString, &HeaderLineWidth, 0);
23867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          FreePool (StringPtr);
23877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          StringPtr       = GetToken (STRING_TOKEN(ADJUST_HELP_PAGE_DOWN), gHiiHandle);
23887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (HelpBottomString != NULL) {
23897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            FreePool (HelpBottomString);
23907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            HelpBottomString = NULL;
23917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
23927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          HelpBottomLine  = ProcessHelpString (StringPtr, &HelpBottomString, &BottomLineWidth, 0);
23937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          FreePool (StringPtr);
23947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
23957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Calculate the help page count.
23967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
23977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (HelpLine > 2 * RowCount - 2) {
23987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            HelpPageCount = (HelpLine - RowCount + 1) / (RowCount - 2) + 1;
23997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            if ((HelpLine - RowCount + 1) % (RowCount - 2) > 1) {
24007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              HelpPageCount += 1;
24017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            }
24027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          } else {
24037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            HelpPageCount = 2;
24047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
24057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else {
24067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          MultiHelpPage = FALSE;
24077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
24087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
24097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
24107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
24117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Check whether need to show the 'More(U/u)' at the begin.
24127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Base on current direct info, here shows aligned to the right side of the column.
24137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // If the direction is multi line and aligned to right side may have problem, so
24147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // add ASSERT code here.
24157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
24167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (HelpPageIndex > 0) {
24177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        gST->ConOut->SetAttribute (gST->ConOut, GetInfoTextColor ());
24187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        for (Index = 0; Index < HelpHeaderLine; Index++) {
24197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ASSERT (HelpHeaderLine == 1);
24207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ASSERT (GetStringWidth (HelpHeaderString) / 2 < (UINTN) (gHelpBlockWidth - 1));
24217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          PrintStringAtWithWidth (
24227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gStatementDimensions.RightColumn - gHelpBlockWidth,
24237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Index + TopRow,
24247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gEmptyString,
24257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gHelpBlockWidth
24267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            );
24277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          PrintStringAt (
24287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gStatementDimensions.RightColumn - GetStringWidth (HelpHeaderString) / 2 - 1,
24297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Index + TopRow,
24307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            &HelpHeaderString[Index * HeaderLineWidth]
24317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            );
24327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
24337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
24347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
24357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      gST->ConOut->SetAttribute (gST->ConOut, GetHelpTextColor ());
24367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
24377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Print the help string info.
24387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
24397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (!MultiHelpPage) {
24407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        for (Index = 0; Index < HelpLine; Index++) {
24417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          PrintStringAtWithWidth (
24427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gStatementDimensions.RightColumn - gHelpBlockWidth,
24437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Index + TopRow,
24447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            &HelpString[Index * EachLineWidth],
24457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gHelpBlockWidth
24467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            );
24477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
24487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        for (; Index < RowCount; Index ++) {
24497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          PrintStringAtWithWidth (
24507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gStatementDimensions.RightColumn - gHelpBlockWidth,
24517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Index + TopRow,
24527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gEmptyString,
24537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gHelpBlockWidth
24547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            );
24557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
24567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        gST->ConOut->SetCursorPosition(gST->ConOut, gStatementDimensions.RightColumn-1, BottomRow);
24577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      } else  {
24587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (HelpPageIndex == 0) {
24597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          for (Index = 0; Index < RowCount - HelpBottomLine; Index++) {
24607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            PrintStringAtWithWidth (
24617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              gStatementDimensions.RightColumn - gHelpBlockWidth,
24627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              Index + TopRow,
24637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              &HelpString[Index * EachLineWidth],
24647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              gHelpBlockWidth
24657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              );
24667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
24677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else {
24687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          for (Index = 0; (Index < RowCount - HelpBottomLine - HelpHeaderLine) &&
24697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              (Index + HelpPageIndex * (RowCount - 2) + 1 < HelpLine); Index++) {
24707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            PrintStringAtWithWidth (
24717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              gStatementDimensions.RightColumn - gHelpBlockWidth,
24727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              Index + TopRow + HelpHeaderLine,
24737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              &HelpString[(Index + HelpPageIndex * (RowCount - 2) + 1)* EachLineWidth],
24747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              gHelpBlockWidth
24757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              );
24767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
24777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (HelpPageIndex == HelpPageCount - 1) {
24787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            for (; Index < RowCount - HelpHeaderLine; Index ++) {
24797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              PrintStringAtWithWidth (
24807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                gStatementDimensions.RightColumn - gHelpBlockWidth,
24817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                Index + TopRow + HelpHeaderLine,
24827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                gEmptyString,
24837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                gHelpBlockWidth
24847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                );
24857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            }
24867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gST->ConOut->SetCursorPosition(gST->ConOut, gStatementDimensions.RightColumn-1, BottomRow);
24877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
24887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
24897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
24907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
24917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
24927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Check whether need to print the 'More(D/d)' at the bottom.
24937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Base on current direct info, here shows aligned to the right side of the column.
24947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // If the direction is multi line and aligned to right side may have problem, so
24957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // add ASSERT code here.
24967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
24977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (HelpPageIndex < HelpPageCount - 1 && MultiHelpPage) {
24987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        gST->ConOut->SetAttribute (gST->ConOut, GetInfoTextColor ());
24997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        for (Index = 0; Index < HelpBottomLine; Index++) {
25007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ASSERT (HelpBottomLine == 1);
25017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ASSERT (GetStringWidth (HelpBottomString) / 2 < (UINTN) (gHelpBlockWidth - 1));
25027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          PrintStringAtWithWidth (
25037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gStatementDimensions.RightColumn - gHelpBlockWidth,
25047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            BottomRow + Index - HelpBottomLine + 1,
25057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gEmptyString,
25067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gHelpBlockWidth
25077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            );
25087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          PrintStringAt (
25097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gStatementDimensions.RightColumn - GetStringWidth (HelpBottomString) / 2 - 1,
25107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            BottomRow + Index - HelpBottomLine + 1,
25117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            &HelpBottomString[Index * BottomLineWidth]
25127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            );
25137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
25147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
25157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
25167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Reset this flag every time we finish using it.
25177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
25187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Repaint = FALSE;
25197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      NewLine = FALSE;
25207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
25217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
25227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfPrepareToReadKey:
25237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfReadKey;
25247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ScreenOperation = UiNoOperation;
25257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
25267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
25277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfReadKey:
25287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfScreenOperation;
25297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
25307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
25317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Wait for user's selection
25327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
25337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      while (TRUE) {
25347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
25357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (!EFI_ERROR (Status)) {
25367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          EventType = UIEventKey;
25377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
25387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
25397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
25407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
25417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // If we encounter error, continue to read another key in.
25427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
25437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (Status != EFI_NOT_READY) {
25447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          continue;
25457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
25467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
25477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        EventType = UiWaitForEvent(gST->ConIn->WaitForKey);
25487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (EventType == UIEventKey) {
25497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
25507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
25517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
25527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
25537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
25547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (EventType == UIEventDriver) {
25557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        gUserInput->Action = BROWSER_ACTION_NONE;
25567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ControlFlag = CfExit;
25577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
25587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
25597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
25607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (EventType == UIEventTimeOut) {
25617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        gUserInput->Action = BROWSER_ACTION_FORM_EXIT;
25627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ControlFlag = CfExit;
25637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
25647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
25657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
25667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      switch (Key.UnicodeChar) {
25677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case CHAR_CARRIAGE_RETURN:
25687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if(MenuOption == NULL || MenuOption->GrayOut || MenuOption->ReadOnly) {
25697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ControlFlag = CfReadKey;
25707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
25717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
25727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
25737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ScreenOperation = UiSelect;
25747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        gDirection      = 0;
25757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
25767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
25777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
25787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // We will push the adjustment of these numeric values directly to the input handler
25797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //  NOTE: we won't handle manual input numeric
25807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
25817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case '+':
25827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case '-':
25837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
25847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // If the screen has no menu items, and the user didn't select UiReset
25857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // ignore the selection and go back to reading keys.
25867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
25877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if(IsListEmpty (&gMenuOption) || MenuOption->GrayOut || MenuOption->ReadOnly) {
25887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ControlFlag = CfReadKey;
25897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
25907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
25917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
25927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ASSERT(MenuOption != NULL);
25937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Statement = MenuOption->ThisTag;
25947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP)
25957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          || (Statement->OpCode->OpCode == EFI_IFR_TIME_OP)
25967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          || ((Statement->OpCode->OpCode == EFI_IFR_NUMERIC_OP) && (GetFieldFromNum(Statement->OpCode) != 0))
25977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ){
25987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (Key.UnicodeChar == '+') {
25997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gDirection = SCAN_RIGHT;
26007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          } else {
26017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gDirection = SCAN_LEFT;
26027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
26037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Status = ProcessOptions (MenuOption, TRUE, &OptionString, TRUE);
26057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (OptionString != NULL) {
26067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            FreePool (OptionString);
26077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
26087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (EFI_ERROR (Status)) {
26097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
26107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            // Repaint to clear possible error prompt pop-up
26117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
26127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Repaint = TRUE;
26137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            NewLine = TRUE;
26147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          } else {
26157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            ControlFlag = CfExit;
26167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
26177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
26187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
26197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case '^':
26217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ScreenOperation = UiUp;
26227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
26237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case 'V':
26257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case 'v':
26267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ScreenOperation = UiDown;
26277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
26287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case ' ':
26307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if(IsListEmpty (&gMenuOption)) {
26317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ControlFlag = CfReadKey;
26327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
26337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
26347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ASSERT(MenuOption != NULL);
26367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_CHECKBOX_OP && !MenuOption->GrayOut && !MenuOption->ReadOnly) {
26377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ScreenOperation = UiSelect;
26387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
26397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
26407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case 'D':
26427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case 'd':
26437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (!MultiHelpPage) {
26447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ControlFlag = CfReadKey;
26457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
26467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
26477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ControlFlag    = CfUpdateHelpString;
26487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        HelpPageIndex  = HelpPageIndex < HelpPageCount - 1 ? HelpPageIndex + 1 : HelpPageCount - 1;
26497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
26507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case 'U':
26527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case 'u':
26537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (!MultiHelpPage) {
26547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ControlFlag = CfReadKey;
26557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
26567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
26577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ControlFlag    = CfUpdateHelpString;
26587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        HelpPageIndex  = HelpPageIndex > 0 ? HelpPageIndex - 1 : 0;
26597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
26607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case CHAR_NULL:
26627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        for (Index = 0; Index < mScanCodeNumber; Index++) {
26637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (Key.ScanCode == gScanCodeToOperation[Index].ScanCode) {
26647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            ScreenOperation = gScanCodeToOperation[Index].ScreenOperation;
26657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            break;
26667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
26677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
26687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (((FormData->Attribute & HII_DISPLAY_MODAL) != 0) && (Key.ScanCode == SCAN_ESC || Index == mScanCodeNumber)) {
26707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
26717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // ModalForm has no ESC key and Hot Key.
26727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
26737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ControlFlag = CfReadKey;
26747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else if (Index == mScanCodeNumber) {
26757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
26767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Check whether Key matches the registered hot key.
26777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
26787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          HotKey = NULL;
26797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          HotKey = GetHotKeyFromRegisterList (&Key);
26807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (HotKey != NULL) {
26817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            ScreenOperation = UiHotKey;
26827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
26837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
26847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
26857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
26867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
26877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfScreenOperation:
26897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (ScreenOperation != UiReset) {
26907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
26917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // If the screen has no menu items, and the user didn't select UiReset
26927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // ignore the selection and go back to reading keys.
26937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
26947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (IsListEmpty (&gMenuOption)) {
26957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ControlFlag = CfReadKey;
26967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
26977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
26987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
26997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
27007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      for (Index = 0;
27017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong           Index < sizeof (gScreenOperationToControlFlag) / sizeof (gScreenOperationToControlFlag[0]);
27027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong           Index++
27037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ) {
27047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (ScreenOperation == gScreenOperationToControlFlag[Index].ScreenOperation) {
27057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ControlFlag = gScreenOperationToControlFlag[Index].ControlFlag;
27067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
27077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
27087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
27097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
27107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
27117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUiSelect:
27127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfRepaint;
27137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
27147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT(MenuOption != NULL);
27157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Statement = MenuOption->ThisTag;
27167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) {
27177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
27187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
27197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
27207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      switch (Statement->OpCode->OpCode) {
27217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case EFI_IFR_REF_OP:
27227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case EFI_IFR_ACTION_OP:
27237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case EFI_IFR_RESET_BUTTON_OP:
27247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ControlFlag = CfExit;
27257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
27267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
27277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      default:
27287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
27297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Editable Questions: oneof, ordered list, checkbox, numeric, string, password
27307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
27317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        RefreshKeyHelp (gFormData, Statement, TRUE);
27327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Status = ProcessOptions (MenuOption, TRUE, &OptionString, TRUE);
27337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
27347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (OptionString != NULL) {
27357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          FreePool (OptionString);
27367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
27377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
27387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (EFI_ERROR (Status)) {
27397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Repaint = TRUE;
27407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          NewLine = TRUE;
27417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          RefreshKeyHelp (gFormData, Statement, FALSE);
27427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
27437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else {
27447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ControlFlag = CfExit;
27457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
27467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
27477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
27487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
27497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
27507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUiReset:
27517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
27527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // We come here when someone press ESC
27537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // If the policy is not exit front page when user press ESC, process here.
27547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
27557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (!FormExitPolicy()) {
27567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Repaint     = TRUE;
27577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        NewLine     = TRUE;
27587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ControlFlag = CfRepaint;
27597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
27607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
27617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
27627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
27637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // When user press ESC, it will try to show another menu, should clean the gSequence info.
27647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
27657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (gSequence != 0) {
27667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        gSequence = 0;
27677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
27687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
27697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      gUserInput->Action = BROWSER_ACTION_FORM_EXIT;
27707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfExit;
27717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
27727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
27737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUiHotKey:
27747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfRepaint;
27757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
27767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      gUserInput->Action = HotKey->Action;
27777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfExit;
27787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
27797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
27807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUiLeft:
27817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfRepaint;
27827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT(MenuOption != NULL);
27837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)) {
27847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (MenuOption->Sequence != 0) {
27857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
27867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // In the middle or tail of the Date/Time op-code set, go left.
27877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
27887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ASSERT(NewPos != NULL);
27897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          NewPos = NewPos->BackLink;
27907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
27917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
27927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
27937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
27947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUiRight:
27957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfRepaint;
27967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT(MenuOption != NULL);
27977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)) {
27987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (MenuOption->Sequence != 2) {
27997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
28007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // In the middle or tail of the Date/Time op-code set, go left.
28017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
28027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ASSERT(NewPos != NULL);
28037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          NewPos = NewPos->ForwardLink;
28047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
28057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
28067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
28077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
28087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUiUp:
28097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfRepaint;
28107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
28117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      SavedListEntry = NewPos;
28127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
28137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT(NewPos != NULL);
28147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
28157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Adjust Date/Time position before we advance forward.
28167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
28177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      AdjustDateAndTimePosition (TRUE, &NewPos);
28187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (NewPos->BackLink != &gMenuOption) {
28197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        MenuOption = MENU_OPTION_FROM_LINK (NewPos);
28207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ASSERT (MenuOption != NULL);
28217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        NewLine    = TRUE;
28227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        NewPos     = NewPos->BackLink;
28237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
28247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        PreviousMenuOption = MENU_OPTION_FROM_LINK (NewPos);
28257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (PreviousMenuOption->Row == 0) {
28267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          UpdateOptionSkipLines (PreviousMenuOption);
28277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
28287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        DistanceValue = PreviousMenuOption->Skip;
28297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Difference    = 0;
28307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (MenuOption->Row >= DistanceValue + TopRow) {
28317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Difference = MoveToNextStatement (TRUE, &NewPos, MenuOption->Row - TopRow - DistanceValue);
28327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
28337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
28347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
28357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (Difference < 0) {
28367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
28377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // We hit the begining MenuOption that can be focused
28387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // so we simply scroll to the top.
28397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
28407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (TopOfScreen != gMenuOption.ForwardLink) {
28417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            TopOfScreen = gMenuOption.ForwardLink;
28427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Repaint     = TRUE;
28437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          } else {
28447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
28457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            // Scroll up to the last page when we have arrived at top page.
28467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
28477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            NewPos          = &gMenuOption;
28487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            TopOfScreen     = &gMenuOption;
28497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            MenuOption      = MENU_OPTION_FROM_LINK (SavedListEntry);
28507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            ScreenOperation = UiPageUp;
28517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            ControlFlag     = CfScreenOperation;
28527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            break;
28537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
28547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else if (MenuOption->Row < TopRow + DistanceValue + Difference) {
28557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
28567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Previous focus MenuOption is above the TopOfScreen, so we need to scroll
28577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
28587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          TopOfScreen = NewPos;
28597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Repaint     = TRUE;
28607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          SkipValue = 0;
28617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else if (!IsSelectable (NextMenuOption)) {
28627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
28637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Continue to go up until scroll to next page or the selectable option is found.
28647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
28657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ScreenOperation = UiUp;
28667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ControlFlag     = CfScreenOperation;
28677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
28687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
28697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
28707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
28717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
28727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        AdjustDateAndTimePosition (TRUE, &TopOfScreen);
28737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        AdjustDateAndTimePosition (TRUE, &NewPos);
28747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
28757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        UpdateStatusBar (INPUT_ERROR, FALSE);
28767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      } else {
28777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
28787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Scroll up to the last page.
28797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
28807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        NewPos          = &gMenuOption;
28817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        TopOfScreen     = &gMenuOption;
28827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        MenuOption      = MENU_OPTION_FROM_LINK (SavedListEntry);
28837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ScreenOperation = UiPageUp;
28847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ControlFlag     = CfScreenOperation;
28857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
28867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
28877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
28887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUiPageUp:
28897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
28907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // SkipValue means lines is skipped when show the top menu option.
28917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
28927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag     = CfRepaint;
28937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
28947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT(NewPos != NULL);
28957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
28967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Already at the first menu option, Check the skip value.
28977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
28987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (NewPos->BackLink == &gMenuOption) {
28997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (SkipValue == 0) {
29007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          NewLine = FALSE;
29017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Repaint = FALSE;
29027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else {
29037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          NewLine = TRUE;
29047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Repaint = TRUE;
29057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          SkipValue = 0;
29067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
29077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
29087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
29097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
29107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      NewLine   = TRUE;
29117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Repaint   = TRUE;
29127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
29137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
29147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // SkipValue > (BottomRow - TopRow + 1) means current menu has more than one
29157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // form of options to be show, so just update the SkipValue to show the next
29167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // parts of options.
29177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
29187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (SkipValue > (INTN) (BottomRow - TopRow + 1)) {
29197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        SkipValue -= BottomRow - TopRow + 1;
29207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
29217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
29227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
29237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Link      = TopOfScreen;
29247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
29257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // First minus the menu of the top screen, it's value is SkipValue.
29267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
29277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Index     = (BottomRow + 1) - SkipValue;
29287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      while ((Index > TopRow) && (Link->BackLink != &gMenuOption)) {
29297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Link = Link->BackLink;
29307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);
29317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (PreviousMenuOption->Row == 0) {
29327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          UpdateOptionSkipLines (PreviousMenuOption);
29337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
29347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (Index < PreviousMenuOption->Skip) {
29357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
29367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
29377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Index = Index - PreviousMenuOption->Skip;
29387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
29397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
29407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if ((Link->BackLink == &gMenuOption) && (Index >= TopRow)) {
29417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        SkipValue = 0;
29427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (TopOfScreen == &gMenuOption) {
29437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          TopOfScreen = gMenuOption.ForwardLink;
29447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          NewPos      = gMenuOption.BackLink;
29457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow);
29467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Repaint = FALSE;
29477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else if (TopOfScreen != Link) {
29487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          TopOfScreen = Link;
29497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          NewPos      = Link;
29507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
29517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else {
29527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
29537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Finally we know that NewPos is the last MenuOption can be focused.
29547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
29557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Repaint = FALSE;
29567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          NewPos  = Link;
29577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
29587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
29597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      } else {
29607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (Index > TopRow) {
29617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
29627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // At here, only case "Index < PreviousMenuOption->Skip" can reach here.
29637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
29647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          SkipValue = PreviousMenuOption->Skip - (Index - TopRow);
29657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else if (Index == TopRow) {
29667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          SkipValue = 0;
29677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else {
29687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          SkipValue = TopRow - Index;
29697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
29707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
29717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
29727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Move to the option in Next page.
29737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
29747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (TopOfScreen == &gMenuOption) {
29757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          NewPos = gMenuOption.BackLink;
29767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow);
29777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else {
29787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          NewPos = Link;
29797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
29807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
29817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
29827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
29837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // There are more MenuOption needing scrolling up.
29847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
29857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        TopOfScreen = Link;
29867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        MenuOption  = NULL;
29877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
29887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
29897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
29907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
29917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Don't do this when we are already in the first page.
29927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
29937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      AdjustDateAndTimePosition (TRUE, &TopOfScreen);
29947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      AdjustDateAndTimePosition (TRUE, &NewPos);
29957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
29967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
29977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUiPageDown:
29987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
29997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // SkipValue means lines is skipped when show the top menu option.
30007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
30017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag     = CfRepaint;
30027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
30037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT (NewPos != NULL);
30047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (NewPos->ForwardLink == &gMenuOption) {
30057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        NewLine = FALSE;
30067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Repaint = FALSE;
30077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
30087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
30097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
30107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      NewLine = TRUE;
30117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Repaint = TRUE;
30127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Link    = TopOfScreen;
30137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      NextMenuOption = MENU_OPTION_FROM_LINK (Link);
30147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Index = TopRow + NextMenuOption->Skip - SkipValue;
30157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
30167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Count to the menu option which will show at the top of the next form.
30177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
30187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      while ((Index <= BottomRow + 1) && (Link->ForwardLink != &gMenuOption)) {
30197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Link           = Link->ForwardLink;
30207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        NextMenuOption = MENU_OPTION_FROM_LINK (Link);
30217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Index = Index + NextMenuOption->Skip;
30227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
30237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
30247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if ((Link->ForwardLink == &gMenuOption) && (Index <= BottomRow + 1)) {
30257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
30267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Finally we know that NewPos is the last MenuOption can be focused.
30277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
30287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Repaint = FALSE;
30297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        MoveToNextStatement (TRUE, &Link, Index - TopRow);
30307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      } else {
30317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
30327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Calculate the skip line for top of screen menu.
30337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
30347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (Link == TopOfScreen) {
30357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
30367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // The top of screen menu option occupies the entire form.
30377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
30387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          SkipValue += BottomRow - TopRow + 1;
30397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else {
30407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          SkipValue = NextMenuOption->Skip - (Index - (BottomRow + 1));
30417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
30427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
30437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        TopOfScreen = Link;
30447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        MenuOption = NULL;
30457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
30467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Move to the Next selectable menu.
30477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
30487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        MoveToNextStatement (FALSE, &Link, BottomRow - TopRow);
30497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
30507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
30517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
30527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Save the menu as the next highlight menu.
30537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
30547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      NewPos  = Link;
30557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
30567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
30577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
30587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Don't do this when we are already in the last page.
30597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
30607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      AdjustDateAndTimePosition (TRUE, &TopOfScreen);
30617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      AdjustDateAndTimePosition (TRUE, &NewPos);
30627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
30637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
30647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUiDown:
30657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
30667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // SkipValue means lines is skipped when show the top menu option.
30677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // NewPos  points to the menu which is highlighted now.
30687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
30697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfRepaint;
30707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
30717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
30727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Since the behavior of hitting the down arrow on a Date/Time op-code is intended
30737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // to be one that progresses to the next set of op-codes, we need to advance to the last
30747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Date/Time op-code and leave the remaining logic in UiDown intact so the appropriate
30757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // checking can be done.  The only other logic we need to introduce is that if a Date/Time
30767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // op-code is the last entry in the menu, we need to rewind back to the first op-code of
30777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // the Date/Time op-code.
30787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
30797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      SavedListEntry = NewPos;
30807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      AdjustDateAndTimePosition (FALSE, &NewPos);
30817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
30827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (NewPos->ForwardLink != &gMenuOption) {
30837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        MenuOption      = MENU_OPTION_FROM_LINK (NewPos);
30847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        NewLine         = TRUE;
30857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        NewPos          = NewPos->ForwardLink;
30867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
30877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Difference      = 0;
30887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
30897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Current menu not at the bottom of the form.
30907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
30917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (BottomRow >= MenuOption->Row + MenuOption->Skip) {
30927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
30937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Find the next selectable menu.
30947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
30957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Difference = MoveToNextStatement (FALSE, &NewPos, BottomRow - MenuOption->Row - MenuOption->Skip);
30967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
30977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // We hit the end of MenuOption that can be focused
30987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // so we simply scroll to the first page.
30997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
31007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (Difference < 0) {
31017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
31027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            // Scroll to the first page.
31037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
31047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            if (TopOfScreen != gMenuOption.ForwardLink) {
31057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              TopOfScreen = gMenuOption.ForwardLink;
31067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              Repaint     = TRUE;
31077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              MenuOption  = NULL;
31087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            } else {
31097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
31107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            }
31117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            NewPos        = gMenuOption.ForwardLink;
31127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
31137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
31147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            SkipValue = 0;
31157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
31167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
31177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
31187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            AdjustDateAndTimePosition (TRUE, &TopOfScreen);
31197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            AdjustDateAndTimePosition (TRUE, &NewPos);
31207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            break;
31217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
31227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
31237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        NextMenuOption  = MENU_OPTION_FROM_LINK (NewPos);
31247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (NextMenuOption->Row == 0) {
31257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          UpdateOptionSkipLines (NextMenuOption);
31267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
31277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        DistanceValue  = Difference + NextMenuOption->Skip;
31287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
31297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Temp = MenuOption->Row + MenuOption->Skip + DistanceValue - 1;
31307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if ((MenuOption->Row + MenuOption->Skip == BottomRow + 1) &&
31317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            (NextMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP ||
31327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong             NextMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)
31337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            ) {
31347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Temp ++;
31357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
31367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
31377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
31387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // If we are going to scroll, update TopOfScreen
31397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
31407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (Temp > BottomRow) {
31417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          do {
31427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
31437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            // Is the current top of screen a zero-advance op-code?
31447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            // If so, keep moving forward till we hit a >0 advance op-code
31457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
31467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
31477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
31487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
31497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            // If bottom op-code is more than one line or top op-code is more than one line
31507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
31517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            if ((DistanceValue > 1) || (SavedMenuOption->Skip > 1)) {
31527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              //
31537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              // Is the bottom op-code greater than or equal in size to the top op-code?
31547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              //
31557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              if ((Temp - BottomRow) >= (SavedMenuOption->Skip - SkipValue)) {
31567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                //
31577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                // Skip the top op-code
31587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                //
31597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                TopOfScreen     = TopOfScreen->ForwardLink;
31607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                Difference      = (Temp - BottomRow) - (SavedMenuOption->Skip - SkipValue);
31617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
31627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
31637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
31647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                //
31657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                // If we have a remainder, skip that many more op-codes until we drain the remainder
31667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                //
31677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                while (Difference >= (INTN) SavedMenuOption->Skip) {
31687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  //
31697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  // Since the Difference is greater than or equal to this op-code's skip value, skip it
31707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  //
31717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  Difference      = Difference - (INTN) SavedMenuOption->Skip;
31727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  TopOfScreen     = TopOfScreen->ForwardLink;
31737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
31747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                }
31757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                //
31767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                // Since we will act on this op-code in the next routine, and increment the
31777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                // SkipValue, set the skips to one less than what is required.
31787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                //
31797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                SkipValue = Difference - 1;
31807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              } else {
31817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                //
31827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                // Since we will act on this op-code in the next routine, and increment the
31837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                // SkipValue, set the skips to one less than what is required.
31847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                //
31857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                SkipValue += (Temp - BottomRow) - 1;
31867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              }
31877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            } else {
31887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              if ((SkipValue + 1) == (INTN) SavedMenuOption->Skip) {
31897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                TopOfScreen = TopOfScreen->ForwardLink;
31907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                break;
31917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              }
31927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            }
31937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
31947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            // If the op-code at the top of the screen is more than one line, let's not skip it yet
31957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            // Let's set a skip flag to smoothly scroll the top of the screen.
31967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
31977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            if (SavedMenuOption->Skip > 1) {
31987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              if (SavedMenuOption == NextMenuOption) {
31997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                SkipValue = 0;
32007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              } else {
32017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                SkipValue++;
32027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              }
32037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            } else if (SavedMenuOption->Skip == 1) {
32047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              SkipValue   = 0;
32057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            } else {
32067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              SkipValue   = 0;
32077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              TopOfScreen = TopOfScreen->ForwardLink;
32087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            }
32097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          } while (SavedMenuOption->Skip == 0);
32107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Repaint       = TRUE;
32127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else if (!IsSelectable (NextMenuOption)) {
32137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
32147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Continue to go down until scroll to next page or the selectable option is found.
32157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
32167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ScreenOperation = UiDown;
32177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ControlFlag     = CfScreenOperation;
32187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
32197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
32217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        UpdateStatusBar (INPUT_ERROR, FALSE);
32237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      } else {
32257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
32267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Scroll to the first page.
32277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
32287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (TopOfScreen != gMenuOption.ForwardLink) {
32297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          TopOfScreen = gMenuOption.ForwardLink;
32307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Repaint     = TRUE;
32317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          MenuOption  = NULL;
32327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else {
32337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
32347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Need to remove the current highlight menu.
32357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // MenuOption saved the last highlight menu info.
32367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
32377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
32387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
32397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        SkipValue     = 0;
32417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        NewLine       = TRUE;
32427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
32437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Get the next highlight menu.
32447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
32457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        NewPos        = gMenuOption.ForwardLink;
32467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
32477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
32487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
32507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
32517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
32527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      AdjustDateAndTimePosition (TRUE, &TopOfScreen);
32537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      AdjustDateAndTimePosition (TRUE, &NewPos);
32547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
32557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUiNoOperation:
32577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfRepaint;
32587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
32597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfExit:
32615a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong      gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
32627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (HelpString != NULL) {
32637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        FreePool (HelpString);
32647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
32657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (HelpHeaderString != NULL) {
32667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        FreePool (HelpHeaderString);
32677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
32687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (HelpBottomString != NULL) {
32697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        FreePool (HelpBottomString);
32707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
32717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      return EFI_SUCCESS;
32727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    default:
32747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
32757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
32767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
32777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
32787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
32807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Base on the browser status info to show an pop up message.
32827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
32847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
32857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongBrowserStatusProcess (
32867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  VOID
32877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
32887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
32897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16         *ErrorInfo;
32907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_INPUT_KEY  Key;
32917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (gFormData->BrowserStatus == BROWSER_SUCCESS) {
32937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return;
32947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
32957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (gFormData->ErrorString != NULL) {
32977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ErrorInfo = gFormData->ErrorString;
32987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else {
32997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    switch (gFormData->BrowserStatus) {
33007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case BROWSER_SUBMIT_FAIL:
33017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ErrorInfo = gSaveFailed;
33027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
33037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case BROWSER_NO_SUBMIT_IF:
33057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ErrorInfo = gNoSubmitIf;
33067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
33077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case BROWSER_FORM_NOT_FOUND:
33097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ErrorInfo = gFormNotFound;
33107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
33117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case BROWSER_FORM_SUPPRESS:
33137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ErrorInfo = gFormSuppress;
33147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
33157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case BROWSER_PROTOCOL_NOT_FOUND:
33177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ErrorInfo = gProtocolNotFound;
33187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
33197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    default:
33217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ErrorInfo = gBrwoserError;
33227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
33237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
33247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
33257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
33277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Error occur, prompt error message.
33287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
33297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  do {
33307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL);
33317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
33327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
33337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
33357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Display one form, and return user input.
33367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param FormData                Form Data to be shown.
33387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param UserInputData           User input data.
33397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval EFI_SUCCESS            1.Form Data is shown, and user input is got.
33417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                                 2.Error info has show and return.
33427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval EFI_INVALID_PARAMETER  The input screen dimension is not valid
33437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval EFI_NOT_FOUND          New form data has some error.
33447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
33457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFI_STATUS
33467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFIAPI
33477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongFormDisplay (
33487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  FORM_DISPLAY_ENGINE_FORM  *FormData,
33497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OUT USER_INPUT                *UserInputData
33507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
33517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
33527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_STATUS  Status;
33537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT (FormData != NULL);
33557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (FormData == NULL) {
33567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return EFI_INVALID_PARAMETER;
33577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
33587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gUserInput = UserInputData;
33607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gFormData  = FormData;
33617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
33637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Process the status info first.
33647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
33657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BrowserStatusProcess();
33667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (UserInputData == NULL) {
33677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
33687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // UserInputData == NULL, means only need to print the error info, return here.
33697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
33707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return EFI_SUCCESS;
33717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
33727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ConvertStatementToMenu();
33747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Status = DisplayPageFrame (FormData, &gStatementDimensions);
33767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (EFI_ERROR (Status)) {
33777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return Status;
33787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
33797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33805a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  //
33815a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  // Check whether layout is changed.
33825a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  //
33835a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  if (mIsFirstForm
33845a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong      || (gOldFormEntry.HiiHandle != FormData->HiiHandle)
33855a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong      || (!CompareGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid))
33865a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong      || (gOldFormEntry.FormId != FormData->FormId)) {
33877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    mStatementLayoutIsChanged = TRUE;
33885a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  } else {
33895a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong    mStatementLayoutIsChanged = FALSE;
33907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
33917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Status = UiDisplayMenu(FormData);
33935a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong
33945a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  //
33955a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  // Backup last form info.
33965a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  //
33975a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  mIsFirstForm            = FALSE;
33985a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  gOldFormEntry.HiiHandle = FormData->HiiHandle;
33995a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  CopyGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid);
34005a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  gOldFormEntry.FormId    = FormData->FormId;
34017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
34027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return Status;
34037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
34047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
34057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
34065a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  Clear Screen to the initial state.
34075a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong**/
34085a9f73bf065eda6b830445dc907e778f4a13d8d7Eric DongVOID
34095a9f73bf065eda6b830445dc907e778f4a13d8d7Eric DongEFIAPI
34105a9f73bf065eda6b830445dc907e778f4a13d8d7Eric DongDriverClearDisplayPage (
34115a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  VOID
34125a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  )
34135a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong{
34145a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  ClearDisplayPage ();
34155a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  mIsFirstForm = TRUE;
34165a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong}
34175a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong
34185a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong/**
34195a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  Set Buffer to Value for Size bytes.
34205a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong
34215a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  @param  Buffer                 Memory to set.
34225a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  @param  Size                   Number of bytes to set
34235a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  @param  Value                  Value of the set operation.
34245a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong
34255a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong**/
34265a9f73bf065eda6b830445dc907e778f4a13d8d7Eric DongVOID
34275a9f73bf065eda6b830445dc907e778f4a13d8d7Eric DongSetUnicodeMem (
34285a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  IN VOID   *Buffer,
34295a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  IN UINTN  Size,
34305a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  IN CHAR16 Value
34315a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  )
34325a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong{
34335a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  CHAR16  *Ptr;
34345a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong
34355a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  Ptr = Buffer;
34365a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  while ((Size--)  != 0) {
34375a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong    *(Ptr++) = Value;
34385a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  }
34395a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong}
34405a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong
34415a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong/**
34427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Initialize Setup Browser driver.
34437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
34447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param ImageHandle     The image handle.
34457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param SystemTable     The system table.
34467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
34477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval EFI_SUCCESS    The Setup Browser module is initialized correctly..
34487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return Other value if failed to initialize the Setup Browser module.
34497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
34507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
34517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFI_STATUS
34527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFIAPI
34537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongInitializeDisplayEngine (
34547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN EFI_HANDLE           ImageHandle,
34557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN EFI_SYSTEM_TABLE     *SystemTable
34567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
34577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
34587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_STATUS                          Status;
34597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_INPUT_KEY                       HotKey;
34607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_STRING                          NewString;
34617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL *FormBrowserEx2;
34627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
34637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
34647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Publish our HII data
34657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
34667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gHiiHandle = HiiAddPackages (
34677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                 &gDisplayEngineGuid,
34687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                 ImageHandle,
34697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                 DisplayEngineStrings,
34707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                 NULL
34717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                 );
34727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT (gHiiHandle != NULL);
34737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
34747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
34757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Install Form Display protocol
34767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
34777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Status = gBS->InstallProtocolInterface (
34787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  &mPrivateData.Handle,
34797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  &gEdkiiFormDisplayEngineProtocolGuid,
34807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  EFI_NATIVE_INTERFACE,
34817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  &mPrivateData.FromDisplayProt
34827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  );
34837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT_EFI_ERROR (Status);
34847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
34857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  InitializeDisplayStrings();
34865a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong
34875a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  ZeroMem (&gHighligthMenuInfo, sizeof (gHighligthMenuInfo));
34885a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  ZeroMem (&gOldFormEntry, sizeof (gOldFormEntry));
34897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
34907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
34917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Use BrowserEx2 protocol to register HotKey.
34927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
34937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Status = gBS->LocateProtocol (&gEdkiiFormBrowserEx2ProtocolGuid, NULL, (VOID **) &FormBrowserEx2);
34947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (!EFI_ERROR (Status)) {
34957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
34967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Register the default HotKey F9 and F10 again.
34977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
34987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    HotKey.UnicodeChar = CHAR_NULL;
34997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    HotKey.ScanCode   = SCAN_F10;
35007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    NewString         = HiiGetString (gHiiHandle, STRING_TOKEN (FUNCTION_TEN_STRING), NULL);
35017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ASSERT (NewString != NULL);
35027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    FormBrowserEx2->RegisterHotKey (&HotKey, BROWSER_ACTION_SUBMIT, 0, NewString);
35037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
35047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    HotKey.ScanCode   = SCAN_F9;
35057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    NewString         = HiiGetString (gHiiHandle, STRING_TOKEN (FUNCTION_NINE_STRING), NULL);
35067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ASSERT (NewString != NULL);
35077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    FormBrowserEx2->RegisterHotKey (&HotKey, BROWSER_ACTION_DEFAULT, EFI_HII_DEFAULT_CLASS_STANDARD, NewString);
35087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
35097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
35107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return EFI_SUCCESS;
35117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
35127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
35137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
35147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  This is the default unload handle for display core drivers.
35157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
35167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param[in]  ImageHandle       The drivers' driver image.
35177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
35187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval EFI_SUCCESS           The image is unloaded.
35197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval Others                Failed to unload the image.
35207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
35217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
35227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFI_STATUS
35237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFIAPI
35247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUnloadDisplayEngine (
35257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN EFI_HANDLE             ImageHandle
35267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
35277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
35287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HiiRemovePackages(gHiiHandle);
35297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
35307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreeDisplayStrings ();
35317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
35327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return EFI_SUCCESS;
35337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
3534