17c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/** @file
27c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEntry and initialization module for the browser.
37c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
423c7d4258f3a916c916f16e1cdf4c217a539b984Eric DongCopyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
5c4866c7710c250b83018de6a1fcde6433f87ff3eSamer El-Haj-Mahmoud elhaj <Samer El-Haj-MahmoudCopyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR>
67c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongThis program and the accompanying materials
77c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dongare licensed and made available under the terms and conditions of the BSD License
87c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dongwhich accompanies this distribution.  The full text of the license may be found at
97c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Donghttp://opensource.org/licenses/bsd-license.php
107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong#include "FormDisplay.h"
177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong//
197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong// Search table for UiDisplayMenu()
207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong//
217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongSCAN_CODE_TO_SCREEN_OPERATION     gScanCodeToOperation[] = {
227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    SCAN_UP,
247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiUp,
257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    SCAN_DOWN,
287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiDown,
297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    SCAN_PAGE_UP,
327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiPageUp,
337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    SCAN_PAGE_DOWN,
367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiPageDown,
377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    SCAN_ESC,
407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiReset,
417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    SCAN_LEFT,
447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiLeft,
457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    SCAN_RIGHT,
487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiRight,
497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong};
517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUINTN mScanCodeNumber = sizeof (gScanCodeToOperation) / sizeof (gScanCodeToOperation[0]);
537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongSCREEN_OPERATION_T0_CONTROL_FLAG  gScreenOperationToControlFlag[] = {
557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiNoOperation,
577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CfUiNoOperation,
587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiSelect,
617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CfUiSelect,
627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiUp,
657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CfUiUp,
667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiDown,
697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CfUiDown,
707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiLeft,
737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CfUiLeft,
747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiRight,
777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CfUiRight,
787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiReset,
817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CfUiReset,
827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiPageUp,
857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CfUiPageUp,
867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiPageDown,
897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CfUiPageDown
907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  },
917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiHotKey,
937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CfUiHotKey
947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong};
967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFI_GUID  gDisplayEngineGuid = {
987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  0xE38C1029, 0xE38F, 0x45b9, {0x8F, 0x0D, 0xE2, 0xE6, 0x0B, 0xC9, 0xB2, 0x62}
997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong};
1007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10142645c3dcf0488c616422dcdfd1596939223f432Eric DongBOOLEAN                       gMisMatch;
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//
116f2e7732e446f9120e83673abb2c701aa7cba17f7Eric DongCHAR16            *gReconnectConfirmChanges;
117f2e7732e446f9120e83673abb2c701aa7cba17f7Eric DongCHAR16            *gReconnectFail;
118f2e7732e446f9120e83673abb2c701aa7cba17f7Eric DongCHAR16            *gReconnectRequired;
119f2e7732e446f9120e83673abb2c701aa7cba17f7Eric DongCHAR16            *gChangesOpt;
1207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gFormNotFound;
1217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gNoSubmitIf;
122f2e7732e446f9120e83673abb2c701aa7cba17f7Eric DongCHAR16            *gBrowserError;
1237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gSaveFailed;
1244d4deaaccb9b39106775d260ea0397c1991b0f04Eric DongCHAR16            *gNoSubmitIfFailed;
1254d4deaaccb9b39106775d260ea0397c1991b0f04Eric DongCHAR16            *gSaveProcess;
1264d4deaaccb9b39106775d260ea0397c1991b0f04Eric DongCHAR16            *gSaveNoSubmitProcess;
1274d4deaaccb9b39106775d260ea0397c1991b0f04Eric DongCHAR16            *gDiscardChange;
1284d4deaaccb9b39106775d260ea0397c1991b0f04Eric DongCHAR16            *gJumpToFormSet;
1294d4deaaccb9b39106775d260ea0397c1991b0f04Eric DongCHAR16            *gCheckError;
1307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gPromptForData;
1317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gPromptForPassword;
1327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gPromptForNewPassword;
1337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gConfirmPassword;
1347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gConfirmError;
1357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gPassowordInvalid;
1367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gPressEnter;
1377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gEmptyString;
1387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gMiniString;
1397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gOptionMismatch;
1407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gFormSuppress;
1417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *gProtocolNotFound;
14223c7d4258f3a916c916f16e1cdf4c217a539b984Eric DongCHAR16            *gConfirmDefaultMsg;
14323c7d4258f3a916c916f16e1cdf4c217a539b984Eric DongCHAR16            *gConfirmSubmitMsg;
14423c7d4258f3a916c916f16e1cdf4c217a539b984Eric DongCHAR16            *gConfirmDiscardMsg;
14523c7d4258f3a916c916f16e1cdf4c217a539b984Eric DongCHAR16            *gConfirmResetMsg;
14623c7d4258f3a916c916f16e1cdf4c217a539b984Eric DongCHAR16            *gConfirmExitMsg;
14723c7d4258f3a916c916f16e1cdf4c217a539b984Eric DongCHAR16            *gConfirmSubmitMsg2nd;
14823c7d4258f3a916c916f16e1cdf4c217a539b984Eric DongCHAR16            *gConfirmDefaultMsg2nd;
14923c7d4258f3a916c916f16e1cdf4c217a539b984Eric DongCHAR16            *gConfirmResetMsg2nd;
15023c7d4258f3a916c916f16e1cdf4c217a539b984Eric DongCHAR16            *gConfirmExitMsg2nd;
15123c7d4258f3a916c916f16e1cdf4c217a539b984Eric DongCHAR16            *gConfirmOpt;
15223c7d4258f3a916c916f16e1cdf4c217a539b984Eric DongCHAR16            *gConfirmOptYes;
15323c7d4258f3a916c916f16e1cdf4c217a539b984Eric DongCHAR16            *gConfirmOptNo;
15423c7d4258f3a916c916f16e1cdf4c217a539b984Eric DongCHAR16            *gConfirmMsgConnect;
15523c7d4258f3a916c916f16e1cdf4c217a539b984Eric DongCHAR16            *gConfirmMsgEnd;
156af047db78d297ca33dd74e5e749166bb17a4cc4eEric DongCHAR16            gModalSkipColumn;
1577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            gPromptBlockWidth;
1587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            gOptionBlockWidth;
1597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            gHelpBlockWidth;
1607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16            *mUnknownString;
1617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongFORM_DISPLAY_DRIVER_PRIVATE_DATA  mPrivateData = {
1637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FORM_DISPLAY_DRIVER_SIGNATURE,
1647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  NULL,
1657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  {
1667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    FormDisplay,
1675a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong    DriverClearDisplayPage,
1687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ConfirmDataChange
1697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
1707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong};
1717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
1747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Get the string based on the StringId and HII Package List Handle.
1757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Token                  The String's ID.
1777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  HiiHandle              The package list in the HII database to search for
1787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                                 the specified string.
1797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return The output string.
1817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
1837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCHAR16 *
1847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongGetToken (
1857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  EFI_STRING_ID                Token,
1867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  EFI_HII_HANDLE               HiiHandle
1877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
1887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
1897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_STRING  String;
1907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  String = HiiGetString (HiiHandle, Token, NULL);
1927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (String == NULL) {
1937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    String = AllocateCopyPool (StrSize (mUnknownString), mUnknownString);
1947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ASSERT (String != NULL);
1957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
1967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return (CHAR16 *) String;
1987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
1997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
2027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Initialize the HII String Token to the correct values.
2037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
2057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
2067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongInitializeDisplayStrings (
2077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  VOID
2087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
2097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
210f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong  gReconnectConfirmChanges = GetToken (STRING_TOKEN (RECONNECT_CONFIRM_CHANGES), gHiiHandle);
2117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  mUnknownString        = GetToken (STRING_TOKEN (UNKNOWN_STRING), gHiiHandle);
2127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gSaveFailed           = GetToken (STRING_TOKEN (SAVE_FAILED), gHiiHandle);
2134d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong  gNoSubmitIfFailed     = GetToken (STRING_TOKEN (NO_SUBMIT_IF_CHECK_FAILED), gHiiHandle);
214f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong  gReconnectFail        = GetToken (STRING_TOKEN (RECONNECT_FAILED), gHiiHandle);
215f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong  gReconnectRequired    = GetToken (STRING_TOKEN (RECONNECT_REQUIRED), gHiiHandle);
216f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong  gChangesOpt           = GetToken (STRING_TOKEN (RECONNECT_CHANGES_OPTIONS), gHiiHandle);
2174d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong  gSaveProcess          = GetToken (STRING_TOKEN (DISCARD_OR_JUMP), gHiiHandle);
2184d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong  gSaveNoSubmitProcess  = GetToken (STRING_TOKEN (DISCARD_OR_CHECK), gHiiHandle);
2194d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong  gDiscardChange        = GetToken (STRING_TOKEN (DISCARD_OR_JUMP_DISCARD), gHiiHandle);
2204d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong  gJumpToFormSet        = GetToken (STRING_TOKEN (DISCARD_OR_JUMP_JUMP), gHiiHandle);
2214d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong  gCheckError           = GetToken (STRING_TOKEN (DISCARD_OR_CHECK_CHECK), gHiiHandle);
2227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gPromptForData        = GetToken (STRING_TOKEN (PROMPT_FOR_DATA), gHiiHandle);
2237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gPromptForPassword    = GetToken (STRING_TOKEN (PROMPT_FOR_PASSWORD), gHiiHandle);
2247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gPromptForNewPassword = GetToken (STRING_TOKEN (PROMPT_FOR_NEW_PASSWORD), gHiiHandle);
2257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gConfirmPassword      = GetToken (STRING_TOKEN (CONFIRM_PASSWORD), gHiiHandle);
2267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gConfirmError         = GetToken (STRING_TOKEN (CONFIRM_ERROR), gHiiHandle);
2277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gPassowordInvalid     = GetToken (STRING_TOKEN (PASSWORD_INVALID), gHiiHandle);
2287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gPressEnter           = GetToken (STRING_TOKEN (PRESS_ENTER), gHiiHandle);
2297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gEmptyString          = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
2307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gMiniString           = GetToken (STRING_TOKEN (MINI_STRING), gHiiHandle);
2317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gOptionMismatch       = GetToken (STRING_TOKEN (OPTION_MISMATCH), gHiiHandle);
2327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gFormSuppress         = GetToken (STRING_TOKEN (FORM_SUPPRESSED), gHiiHandle);
2337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gProtocolNotFound     = GetToken (STRING_TOKEN (PROTOCOL_NOT_FOUND), gHiiHandle);
2347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gFormNotFound         = GetToken (STRING_TOKEN (STATUS_BROWSER_FORM_NOT_FOUND), gHiiHandle);
2357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gNoSubmitIf           = GetToken (STRING_TOKEN (STATUS_BROWSER_NO_SUBMIT_IF), gHiiHandle);
236f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong  gBrowserError         = GetToken (STRING_TOKEN (STATUS_BROWSER_ERROR), gHiiHandle);
23723c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  gConfirmDefaultMsg    = GetToken (STRING_TOKEN (CONFIRM_DEFAULT_MESSAGE), gHiiHandle);
23823c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  gConfirmDiscardMsg    = GetToken (STRING_TOKEN (CONFIRM_DISCARD_MESSAGE), gHiiHandle);
23923c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  gConfirmSubmitMsg     = GetToken (STRING_TOKEN (CONFIRM_SUBMIT_MESSAGE), gHiiHandle);
24023c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  gConfirmResetMsg      = GetToken (STRING_TOKEN (CONFIRM_RESET_MESSAGE), gHiiHandle);
24123c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  gConfirmExitMsg       = GetToken (STRING_TOKEN (CONFIRM_EXIT_MESSAGE), gHiiHandle);
24223c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  gConfirmDefaultMsg2nd = GetToken (STRING_TOKEN (CONFIRM_DEFAULT_MESSAGE_2ND), gHiiHandle);
24323c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  gConfirmSubmitMsg2nd  = GetToken (STRING_TOKEN (CONFIRM_SUBMIT_MESSAGE_2ND), gHiiHandle);
24423c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  gConfirmResetMsg2nd   = GetToken (STRING_TOKEN (CONFIRM_RESET_MESSAGE_2ND), gHiiHandle);
24523c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  gConfirmExitMsg2nd    = GetToken (STRING_TOKEN (CONFIRM_EXIT_MESSAGE_2ND), gHiiHandle);
24623c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  gConfirmOpt           = GetToken (STRING_TOKEN (CONFIRM_OPTION), gHiiHandle);
24723c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  gConfirmOptYes        = GetToken (STRING_TOKEN (CONFIRM_OPTION_YES), gHiiHandle);
24823c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  gConfirmOptNo         = GetToken (STRING_TOKEN (CONFIRM_OPTION_NO), gHiiHandle);
24923c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  gConfirmMsgConnect    = GetToken (STRING_TOKEN (CONFIRM_OPTION_CONNECT), gHiiHandle);
25023c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  gConfirmMsgEnd        = GetToken (STRING_TOKEN (CONFIRM_OPTION_END), gHiiHandle);
2517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
2527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
2547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Free up the resource allocated for all strings required
2557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  by Setup Browser.
2567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
2587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
2597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongFreeDisplayStrings (
2607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  VOID
2617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
2627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
2637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (mUnknownString);
2647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gEmptyString);
2657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gSaveFailed);
2664d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong  FreePool (gNoSubmitIfFailed);
267f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong  FreePool (gReconnectFail);
268f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong  FreePool (gReconnectRequired);
269f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong  FreePool (gChangesOpt);
270f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong  FreePool (gReconnectConfirmChanges);
2714d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong  FreePool (gSaveProcess);
2724d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong  FreePool (gSaveNoSubmitProcess);
2734d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong  FreePool (gDiscardChange);
2744d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong  FreePool (gJumpToFormSet);
2754d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong  FreePool (gCheckError);
2767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gPromptForData);
2777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gPromptForPassword);
2787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gPromptForNewPassword);
2797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gConfirmPassword);
2807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gConfirmError);
2817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gPassowordInvalid);
2827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gPressEnter);
2837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gMiniString);
2847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gOptionMismatch);
2857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gFormSuppress);
2867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gProtocolNotFound);
287f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong  FreePool (gBrowserError);
2887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gNoSubmitIf);
2897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (gFormNotFound);
29023c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  FreePool (gConfirmDefaultMsg);
29123c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  FreePool (gConfirmSubmitMsg);
29223c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  FreePool (gConfirmDiscardMsg);
29323c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  FreePool (gConfirmResetMsg);
29423c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  FreePool (gConfirmExitMsg);
29523c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  FreePool (gConfirmDefaultMsg2nd);
29623c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  FreePool (gConfirmSubmitMsg2nd);
29723c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  FreePool (gConfirmResetMsg2nd);
29823c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  FreePool (gConfirmExitMsg2nd);
29923c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  FreePool (gConfirmOpt);
30023c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  FreePool (gConfirmOptYes);
30123c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  FreePool (gConfirmOptNo);
30223c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  FreePool (gConfirmMsgConnect);
30323c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  FreePool (gConfirmMsgEnd);
3047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
3057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
3077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Get prompt string id from the opcode data buffer.
3087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  OpCode                 The input opcode buffer.
3107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return The prompt string id.
3127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
3147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFI_STRING_ID
3157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongGetPrompt (
3167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN EFI_IFR_OP_HEADER     *OpCode
3177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
3187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
3197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_IFR_STATEMENT_HEADER  *Header;
3207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (OpCode->Length <= sizeof (EFI_IFR_OP_HEADER)) {
3227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return 0;
3237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
3247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Header = (EFI_IFR_STATEMENT_HEADER  *) (OpCode + 1);
3267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return Header->Prompt;
3287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
3297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
3317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Get the supported width for a particular op-code
3327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3336f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong  @param  MenuOption             The menu option.
334af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  AdjustWidth            The width which is saved for the space.
3357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return Returns the number of CHAR16 characters that is support.
3377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
3397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUINT16
3407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongGetWidth (
3416f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong  IN  UI_MENU_OPTION     *MenuOption,
3426f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong  OUT UINT16             *AdjustWidth
3437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
3447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
3456f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong  CHAR16                        *String;
3466f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong  UINTN                         Size;
3476f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong  EFI_IFR_TEXT                  *TestOp;
3486f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong  UINT16                        ReturnWidth;
3496f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong  FORM_DISPLAY_ENGINE_STATEMENT *Statement;
3506f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong
3516f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong  Statement = MenuOption->ThisTag;
3527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
353af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
354af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  // For modal form, clean the entire row.
355af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
356af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  if ((gFormData->Attribute & HII_DISPLAY_MODAL) != 0) {
357ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong    if (AdjustWidth  != NULL) {
358ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong      *AdjustWidth = LEFT_SKIPPED_COLUMNS;
359ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong    }
360ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong    return (UINT16)(gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * (gModalSkipColumn + LEFT_SKIPPED_COLUMNS));
361af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  }
362af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
3637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Size = 0;
3647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
3667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // See if the second text parameter is really NULL
3677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
3687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) {
3697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    TestOp = (EFI_IFR_TEXT *) Statement->OpCode;
3707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (TestOp->TextTwo != 0) {
3717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      String = GetToken (TestOp->TextTwo, gFormData->HiiHandle);
3727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Size   = StrLen (String);
3737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      FreePool (String);
3747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
3757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
3767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if ((Statement->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) ||
3787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      (Statement->OpCode->OpCode == EFI_IFR_REF_OP) ||
3797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      (Statement->OpCode->OpCode == EFI_IFR_PASSWORD_OP) ||
3807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      (Statement->OpCode->OpCode == EFI_IFR_ACTION_OP) ||
3817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      (Statement->OpCode->OpCode == EFI_IFR_RESET_BUTTON_OP) ||
3827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
3837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Allow a wide display if text op-code and no secondary text op-code
3847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
3857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ((Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) && (Size == 0))
3867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ) {
387af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
388af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    //
389af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    // Return the space width.
390af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    //
391af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    if (AdjustWidth != NULL) {
392af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      *AdjustWidth = 2;
393af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    }
394af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    //
395af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    // Keep consistent with current behavior.
396af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    //
3976f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong    ReturnWidth = (UINT16) (gPromptBlockWidth + gOptionBlockWidth - 2);
3986f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong  } else {
3996f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong    if (AdjustWidth != NULL) {
4006f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong      *AdjustWidth = 1;
4016f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong    }
4026f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong
4036f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong    ReturnWidth =  (UINT16) (gPromptBlockWidth - 1);
4047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
4057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4066f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong  //
4076f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong  // For nest in statement, should the subtitle indent.
4086f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong  //
4096f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong  if (MenuOption->NestInStatement) {
4106f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong    ReturnWidth -= SUBTITLE_INDENT;
411af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  }
4126f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong
4136f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong  return ReturnWidth;
4147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
4157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
4177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Will copy LineWidth amount of a string in the OutputString buffer and return the
4187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  number of CHAR16 characters that were copied into the OutputString buffer.
4197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  The output string format is:
4207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Glyph Info + String info + '\0'.
4217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  In the code, it deals \r,\n,\r\n same as \n\r, also it not process the \r or \g.
4237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  InputString            String description for this option.
4257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  LineWidth              Width of the desired string to extract in CHAR16
4267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                                 characters
4277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  GlyphWidth             The glyph width of the begin of the char in the string.
4287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Index                  Where in InputString to start the copy process
4297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  OutputString           Buffer to copy the string into
4307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return Returns the number of CHAR16 characters that were copied into the OutputString
4327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  buffer, include extra glyph info and '\0' info.
4337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
4357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUINT16
4367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongGetLineByWidth (
4377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN      CHAR16                      *InputString,
4387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN      UINT16                      LineWidth,
4397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN OUT  UINT16                      *GlyphWidth,
4407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN OUT  UINTN                       *Index,
4417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OUT     CHAR16                      **OutputString
4427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
4437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
4447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16          StrOffset;
4457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16          GlyphOffset;
4467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16          OriginalGlyphWidth;
4477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BOOLEAN         ReturnFlag;
4487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16          LastSpaceOffset;
4497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16          LastGlyphWidth;
4507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (InputString == NULL || Index == NULL || OutputString == NULL) {
4527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return 0;
4537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
4547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (LineWidth == 0 || *GlyphWidth == 0) {
4567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return 0;
4577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
4587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
4607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Save original glyph width.
4617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
4627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OriginalGlyphWidth = *GlyphWidth;
4637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LastGlyphWidth     = OriginalGlyphWidth;
4647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ReturnFlag         = FALSE;
4657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LastSpaceOffset    = 0;
4667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
4687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric 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.
4697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // To avoid displaying this  empty line in screen,  just skip  the two CHARs here.
4707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
4717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if ((InputString[*Index] == NARROW_CHAR) && (InputString[*Index + 1] == CHAR_CARRIAGE_RETURN)) {
4727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *Index = *Index + 2;
4737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
4747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
4767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Fast-forward the string and see if there is a carriage-return in the string
4777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
4787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  for (StrOffset = 0, GlyphOffset = 0; GlyphOffset <= LineWidth; StrOffset++) {
4797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    switch (InputString[*Index + StrOffset]) {
4807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case NARROW_CHAR:
4817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        *GlyphWidth = 1;
4827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
4837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case WIDE_CHAR:
4857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        *GlyphWidth = 2;
4867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
4877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case CHAR_CARRIAGE_RETURN:
4897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case CHAR_LINEFEED:
4907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case CHAR_NULL:
4917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ReturnFlag = TRUE;
4927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
4937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      default:
4957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        GlyphOffset = GlyphOffset + *GlyphWidth;
4967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
4987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Record the last space info in this line. Will be used in rewind.
4997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
5007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if ((InputString[*Index + StrOffset] == CHAR_SPACE) && (GlyphOffset <= LineWidth)) {
5017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          LastSpaceOffset = StrOffset;
5027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          LastGlyphWidth  = *GlyphWidth;
5037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
5047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
5057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
5067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (ReturnFlag) {
5087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
5097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
5107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
5117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
5137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Rewind the string from the maximum size until we see a space to break the line
5147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
5157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (GlyphOffset > LineWidth) {
5167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
5177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Rewind the string to last space char in this line.
5187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
5197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (LastSpaceOffset != 0) {
5207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      StrOffset   = LastSpaceOffset;
5217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *GlyphWidth = LastGlyphWidth;
5227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
5237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
5247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Roll back to last char in the line width.
5257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
5267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      StrOffset--;
5277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
5287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
5297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
5317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // The CHAR_NULL has process last time, this time just return 0 to stand for the end.
5327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
5337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (StrOffset == 0 && (InputString[*Index + StrOffset] == CHAR_NULL)) {
5347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return 0;
5357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
5367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
5387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Need extra glyph info and '\0' info, so +2.
5397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
5407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  *OutputString = AllocateZeroPool (((UINTN) (StrOffset + 2) * sizeof(CHAR16)));
5417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (*OutputString == NULL) {
5427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return 0;
5437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
5447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
5467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Save the glyph info at the begin of the string, will used by Print function.
5477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
5487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (OriginalGlyphWidth == 1) {
5497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *(*OutputString) = NARROW_CHAR;
5507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else  {
5517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *(*OutputString) = WIDE_CHAR;
5527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
5537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CopyMem ((*OutputString) + 1, &InputString[*Index], StrOffset * sizeof(CHAR16));
5557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (InputString[*Index + StrOffset] == CHAR_SPACE) {
5577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
5587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Skip the space info at the begin of next line.
5597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
5607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *Index = (UINT16) (*Index + StrOffset + 1);
5617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else if (InputString[*Index + StrOffset] == CHAR_LINEFEED) {
5627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
5637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Skip the /n or /n/r info.
5647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
5657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (InputString[*Index + StrOffset + 1] == CHAR_CARRIAGE_RETURN) {
5667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *Index = (UINT16) (*Index + StrOffset + 2);
5677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
5687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *Index = (UINT16) (*Index + StrOffset + 1);
5697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
5707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else if (InputString[*Index + StrOffset] == CHAR_CARRIAGE_RETURN) {
5717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
5727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Skip the /r or /r/n info.
5737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
5747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (InputString[*Index + StrOffset + 1] == CHAR_LINEFEED) {
5757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *Index = (UINT16) (*Index + StrOffset + 2);
5767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
5777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *Index = (UINT16) (*Index + StrOffset + 1);
5787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
5797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else {
5807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *Index = (UINT16) (*Index + StrOffset);
5817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
5827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
5847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Include extra glyph info and '\0' info, so +2.
5857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
5867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return StrOffset + 2;
5877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
5887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
5907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Add one menu option by specified description and context.
5917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Statement              Statement of this Menu Option.
5937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  MenuItemCount          The index for this Option in the Menu.
5947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  NestIn                 Whether this statement is nest in another statement.
5957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
5977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
5987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUiAddMenuOption (
5997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN FORM_DISPLAY_ENGINE_STATEMENT   *Statement,
6007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN UINT16                          *MenuItemCount,
6017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN BOOLEAN                         NestIn
6027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
6037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
6047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_MENU_OPTION   *MenuOption;
6057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN            Index;
6067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN            Count;
6077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16           *String;
6087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16           NumberOfLines;
6097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16           GlyphWidth;
6107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16           Width;
6117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN            ArrayEntry;
6127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16           *OutputString;
6137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_STRING_ID    PromptId;
6147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  NumberOfLines = 1;
6167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ArrayEntry    = 0;
6177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  GlyphWidth    = 1;
6187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Count         = 1;
6197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  MenuOption    = NULL;
6207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  PromptId = GetPrompt (Statement->OpCode);
6227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT (PromptId != 0);
6237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  String = GetToken (PromptId, gFormData->HiiHandle);
6257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT (String != NULL);
6267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
6287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Count = 3;
6297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
6307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  for (Index = 0; Index < Count; Index++) {
6327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    MenuOption = AllocateZeroPool (sizeof (UI_MENU_OPTION));
6337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ASSERT (MenuOption);
6347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    MenuOption->Signature   = UI_MENU_OPTION_SIGNATURE;
6367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    MenuOption->Description = String;
6377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    MenuOption->Handle      = gFormData->HiiHandle;
6387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    MenuOption->ThisTag     = Statement;
6397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    MenuOption->NestInStatement = NestIn;
6407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    MenuOption->EntryNumber = *MenuItemCount;
6417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    MenuOption->Sequence = Index;
6437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if ((Statement->Attribute & HII_DISPLAY_GRAYOUT) != 0) {
6457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption->GrayOut = TRUE;
6467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
6477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption->GrayOut = FALSE;
6487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
6497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if ((Statement->Attribute & HII_DISPLAY_LOCK) != 0 || (gFormData->Attribute & HII_DISPLAY_LOCK) != 0) {
6517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption->GrayOut = TRUE;
6527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
6537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
6557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // If the form or the question has the lock attribute, deal same as grayout.
6567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
6577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if ((gFormData->Attribute & HII_DISPLAY_LOCK) != 0 || (Statement->Attribute & HII_DISPLAY_LOCK) != 0) {
6587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption->GrayOut = TRUE;
6597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
6607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    switch (Statement->OpCode->OpCode) {
6627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_ORDERED_LIST_OP:
6637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_ONE_OF_OP:
6647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_NUMERIC_OP:
6657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_TIME_OP:
6667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_DATE_OP:
6677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_CHECKBOX_OP:
6687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_PASSWORD_OP:
6697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_STRING_OP:
6707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
6717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // User could change the value of these items
6727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
6737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption->IsQuestion = TRUE;
6747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
6757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_TEXT_OP:
6767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (FeaturePcdGet (PcdBrowserGrayOutTextStatement)) {
6777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
6787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Initializing GrayOut option as TRUE for Text setup options
6797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // so that those options will be Gray in colour and un selectable.
6807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
6817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        MenuOption->GrayOut = TRUE;
6827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
6837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
6847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    default:
6857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption->IsQuestion = FALSE;
6867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
6877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
6887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if ((Statement->Attribute & HII_DISPLAY_READONLY) != 0) {
6907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption->ReadOnly = TRUE;
6917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (FeaturePcdGet (PcdBrowerGrayOutReadOnlyMenu)) {
6927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        MenuOption->GrayOut = TRUE;
6937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
6947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
6957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6966f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong    if (Index == 0 &&
6976f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong      (Statement->OpCode->OpCode != EFI_IFR_DATE_OP) &&
6986f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong      (Statement->OpCode->OpCode != EFI_IFR_TIME_OP)) {
6996f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong      Width  = GetWidth (MenuOption, NULL);
7006f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong      for (; GetLineByWidth (String, Width, &GlyphWidth,&ArrayEntry, &OutputString) != 0x0000;) {
7016f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong        //
7026f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong        // If there is more string to process print on the next row and increment the Skip value
7036f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong        //
7046f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong        if (StrLen (&String[ArrayEntry]) != 0) {
7056f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong          NumberOfLines++;
7066f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong        }
7076f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong        FreePool (OutputString);
7086f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong      }
7096f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong    } else {
7106f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong      //
7116f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong      // Add three MenuOptions for Date/Time
7126f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong      // Data format :      [01/02/2004]      [11:22:33]
7136f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong      // Line number :        0  0    1         0  0  1
7146f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong      //
7156f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong      NumberOfLines = 0;
7166f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong    }
7176f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong
7186f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong    if (Index == 2) {
7196f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong      //
7206f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong      // Override LineNumber for the MenuOption in Date/Time sequence
7216f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong      //
7226f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong      MenuOption->Skip = 1;
7236f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong    } else {
7246f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong      MenuOption->Skip = NumberOfLines;
7256f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong    }
7266f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong
7277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    InsertTailList (&gMenuOption, &MenuOption->Link);
7287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
7297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  (*MenuItemCount)++;
7317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
7327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
7347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Create the menu list base on the form data info.
7357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
7377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
7387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongConvertStatementToMenu (
7397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  VOID
7407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
7417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
7427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16                        MenuItemCount;
7437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY                    *Link;
7447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY                    *NestLink;
7457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FORM_DISPLAY_ENGINE_STATEMENT *Statement;
7467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FORM_DISPLAY_ENGINE_STATEMENT *NestStatement;
7477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  MenuItemCount = 0;
7497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  InitializeListHead (&gMenuOption);
7507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Link = GetFirstNode (&gFormData->StatementListHead);
7527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  while (!IsNull (&gFormData->StatementListHead, Link)) {
7537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Statement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);
7547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Link = GetNextNode (&gFormData->StatementListHead, Link);
7557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
7577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Skip the opcode not recognized by Display core.
7587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
7597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (Statement->OpCode->OpCode == EFI_IFR_GUID_OP) {
7607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      continue;
7617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
7627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UiAddMenuOption (Statement, &MenuItemCount, FALSE);
7647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
7667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Check the statement nest in this host statement.
7677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
7687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    NestLink = GetFirstNode (&Statement->NestStatementList);
7697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    while (!IsNull (&Statement->NestStatementList, NestLink)) {
7707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      NestStatement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (NestLink);
7717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      NestLink = GetNextNode (&Statement->NestStatementList, NestLink);
7727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
773077c7aeec07361fc36f8090be46959adb7d38873Eric Dong      //
774077c7aeec07361fc36f8090be46959adb7d38873Eric Dong      // Skip the opcode not recognized by Display core.
775077c7aeec07361fc36f8090be46959adb7d38873Eric Dong      //
776077c7aeec07361fc36f8090be46959adb7d38873Eric Dong      if (NestStatement->OpCode->OpCode == EFI_IFR_GUID_OP) {
777077c7aeec07361fc36f8090be46959adb7d38873Eric Dong        continue;
778077c7aeec07361fc36f8090be46959adb7d38873Eric Dong      }
779077c7aeec07361fc36f8090be46959adb7d38873Eric Dong
7807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      UiAddMenuOption (NestStatement, &MenuItemCount, TRUE);
7817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
7827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
7837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
7847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
7867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Count the storage space of a Unicode string.
7877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  This function handles the Unicode string with NARROW_CHAR
7897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  and WIDE_CHAR control characters. NARROW_HCAR and WIDE_CHAR
7907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  does not count in the resultant output. If a WIDE_CHAR is
7917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  hit, then 2 Unicode character will consume an output storage
7927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  space with size of CHAR16 till a NARROW_CHAR is hit.
7937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  If String is NULL, then ASSERT ().
7957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param String          The input string to be counted.
7977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return Storage space for the input string.
7997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
8017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUINTN
8027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongGetStringWidth (
8037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN CHAR16               *String
8047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
8057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
8067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN Index;
8077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN Count;
8087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN IncrementValue;
8097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT (String != NULL);
8117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (String == NULL) {
8127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return 0;
8137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
8147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Index           = 0;
8167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Count           = 0;
8177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IncrementValue  = 1;
8187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  do {
8207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
8217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Advance to the null-terminator or to the first width directive
8227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
8237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    for (;
8247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong         (String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0);
8257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong         Index++, Count = Count + IncrementValue
8267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        )
8277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ;
8287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
8307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // We hit the null-terminator, we now have a count
8317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
8327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (String[Index] == 0) {
8337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
8347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
8357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
8367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed
8377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2)
8387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
8397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (String[Index] == NARROW_CHAR) {
8407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
8417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Skip to the next character
8427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
8437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Index++;
8447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      IncrementValue = 1;
8457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
8467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
8477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Skip to the next character
8487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
8497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Index++;
8507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      IncrementValue = 2;
8517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
8527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } while (String[Index] != 0);
8537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
8557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Increment by one to include the null-terminator in the size
8567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
8577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Count++;
8587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return Count * sizeof (CHAR16);
8607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
8617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
8637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Base on the input option string to update the skip value for a menu option.
8647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  MenuOption             The MenuOption to be checked.
8667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  OptionString           The input option string.
8677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
8697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
8707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUpdateSkipInfoForMenu (
8717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN UI_MENU_OPTION               *MenuOption,
8727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN CHAR16                       *OptionString
8737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
8747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
8757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN   Index;
8767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16  Width;
8777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN   Row;
8787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16  *OutputString;
8797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16  GlyphWidth;
8807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Width         = (UINT16) gOptionBlockWidth;
8827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  GlyphWidth    = 1;
8837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Row           = 1;
8847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
8867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (StrLen (&OptionString[Index]) != 0) {
8877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Row++;
8887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
8897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    FreePool (OutputString);
8917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
8927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if ((Row > MenuOption->Skip) &&
8947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      (MenuOption->ThisTag->OpCode->OpCode != EFI_IFR_DATE_OP) &&
8957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      (MenuOption->ThisTag->OpCode->OpCode != EFI_IFR_TIME_OP)) {
8967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    MenuOption->Skip = Row;
8977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
8987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
8997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
9017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Update display lines for a Menu Option.
9027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  MenuOption             The MenuOption to be checked.
9047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
9067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
9077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUpdateOptionSkipLines (
9087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN UI_MENU_OPTION               *MenuOption
9097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
9107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
9117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16  *OptionString;
9127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OptionString  = NULL;
9147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ProcessOptions (MenuOption, FALSE, &OptionString, TRUE);
9167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (OptionString != NULL) {
9177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    UpdateSkipInfoForMenu (MenuOption, OptionString);
9187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    FreePool (OptionString);
9207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
9217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if ((MenuOption->ThisTag->OpCode->OpCode  == EFI_IFR_TEXT_OP) && (((EFI_IFR_TEXT*)MenuOption->ThisTag->OpCode)->TextTwo != 0)) {
9237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    OptionString   = GetToken (((EFI_IFR_TEXT*)MenuOption->ThisTag->OpCode)->TextTwo, gFormData->HiiHandle);
9247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (OptionString != NULL) {
9267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      UpdateSkipInfoForMenu (MenuOption, OptionString);
9277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      FreePool (OptionString);
9297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
9307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
9317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
9327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
934ab369468265cd29a90b385a6e950eda3da16636dEric Dong  Check whether this Menu Option could be print.
935ab369468265cd29a90b385a6e950eda3da16636dEric Dong
936ab369468265cd29a90b385a6e950eda3da16636dEric Dong  Check Prompt string, option string or text two string not NULL.
937ab369468265cd29a90b385a6e950eda3da16636dEric Dong
938ab369468265cd29a90b385a6e950eda3da16636dEric Dong  This is an internal function.
939ab369468265cd29a90b385a6e950eda3da16636dEric Dong
940ab369468265cd29a90b385a6e950eda3da16636dEric Dong  @param  MenuOption             The MenuOption to be checked.
941ab369468265cd29a90b385a6e950eda3da16636dEric Dong
942ab369468265cd29a90b385a6e950eda3da16636dEric Dong  @retval TRUE                   This Menu Option is printable.
943ab369468265cd29a90b385a6e950eda3da16636dEric Dong  @retval FALSE                  This Menu Option could not be printable.
944ab369468265cd29a90b385a6e950eda3da16636dEric Dong
945ab369468265cd29a90b385a6e950eda3da16636dEric Dong**/
946ab369468265cd29a90b385a6e950eda3da16636dEric DongBOOLEAN
947ab369468265cd29a90b385a6e950eda3da16636dEric DongPrintableMenu (
948ab369468265cd29a90b385a6e950eda3da16636dEric Dong  UI_MENU_OPTION   *MenuOption
949ab369468265cd29a90b385a6e950eda3da16636dEric Dong  )
950ab369468265cd29a90b385a6e950eda3da16636dEric Dong{
951ab369468265cd29a90b385a6e950eda3da16636dEric Dong  EFI_STATUS    Status;
952ab369468265cd29a90b385a6e950eda3da16636dEric Dong  EFI_STRING    OptionString;
953ab369468265cd29a90b385a6e950eda3da16636dEric Dong
954ab369468265cd29a90b385a6e950eda3da16636dEric Dong  OptionString = NULL;
955ab369468265cd29a90b385a6e950eda3da16636dEric Dong
956ab369468265cd29a90b385a6e950eda3da16636dEric Dong  if (MenuOption->Description[0] != '\0') {
957ab369468265cd29a90b385a6e950eda3da16636dEric Dong    return TRUE;
958ab369468265cd29a90b385a6e950eda3da16636dEric Dong  }
959ab369468265cd29a90b385a6e950eda3da16636dEric Dong
960ab369468265cd29a90b385a6e950eda3da16636dEric Dong  Status = ProcessOptions (MenuOption, FALSE, &OptionString, FALSE);
961ab369468265cd29a90b385a6e950eda3da16636dEric Dong  if (EFI_ERROR (Status)) {
962ab369468265cd29a90b385a6e950eda3da16636dEric Dong    return FALSE;
963ab369468265cd29a90b385a6e950eda3da16636dEric Dong  }
964ab369468265cd29a90b385a6e950eda3da16636dEric Dong  if (OptionString != NULL && OptionString[0] != '\0') {
965ab369468265cd29a90b385a6e950eda3da16636dEric Dong    FreePool (OptionString);
966ab369468265cd29a90b385a6e950eda3da16636dEric Dong    return TRUE;
967ab369468265cd29a90b385a6e950eda3da16636dEric Dong  }
968ab369468265cd29a90b385a6e950eda3da16636dEric Dong
969ab369468265cd29a90b385a6e950eda3da16636dEric Dong  if ((MenuOption->ThisTag->OpCode->OpCode  == EFI_IFR_TEXT_OP) && (((EFI_IFR_TEXT*)MenuOption->ThisTag->OpCode)->TextTwo != 0)) {
970ab369468265cd29a90b385a6e950eda3da16636dEric Dong    OptionString   = GetToken (((EFI_IFR_TEXT*)MenuOption->ThisTag->OpCode)->TextTwo, gFormData->HiiHandle);
971ab369468265cd29a90b385a6e950eda3da16636dEric Dong    ASSERT (OptionString != NULL);
972ab369468265cd29a90b385a6e950eda3da16636dEric Dong    if (OptionString[0] != '\0'){
973ab369468265cd29a90b385a6e950eda3da16636dEric Dong      FreePool (OptionString);
974ab369468265cd29a90b385a6e950eda3da16636dEric Dong      return TRUE;
975ab369468265cd29a90b385a6e950eda3da16636dEric Dong    }
976ab369468265cd29a90b385a6e950eda3da16636dEric Dong  }
977ab369468265cd29a90b385a6e950eda3da16636dEric Dong
978ab369468265cd29a90b385a6e950eda3da16636dEric Dong  return FALSE;
979ab369468265cd29a90b385a6e950eda3da16636dEric Dong}
980ab369468265cd29a90b385a6e950eda3da16636dEric Dong
981ab369468265cd29a90b385a6e950eda3da16636dEric Dong/**
9827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Check whether this Menu Option could be highlighted.
9837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  This is an internal function.
9857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  MenuOption             The MenuOption to be checked.
9877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval TRUE                   This Menu Option is selectable.
9897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval FALSE                  This Menu Option could not be selected.
9907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
9927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongBOOLEAN
9937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongIsSelectable (
9947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_MENU_OPTION   *MenuOption
9957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
9967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
9977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) ||
998ab369468265cd29a90b385a6e950eda3da16636dEric Dong      MenuOption->GrayOut || MenuOption->ReadOnly || !PrintableMenu (MenuOption)) {
9997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return FALSE;
10007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else {
10017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return TRUE;
10027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
10037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
10047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
10067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Move to next selectable statement.
10077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  This is an internal function.
10097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  GoUp                   The navigation direction. TRUE: up, FALSE: down.
10117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  CurrentPosition        Current position.
10127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  GapToTop               Gap position to top or bottom.
1013ab369468265cd29a90b385a6e950eda3da16636dEric Dong  @param  FindInForm             Whether find menu in current form or beyond.
10147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return The row distance from current MenuOption to next selectable MenuOption.
10167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval -1       Reach the begin of the menu, still can't find the selectable menu.
1018ab369468265cd29a90b385a6e950eda3da16636dEric Dong  @retval Value    Find the selectable menu, maybe the truly selectable, maybe the
1019ab369468265cd29a90b385a6e950eda3da16636dEric Dong                   first menu showing beyond current form or last menu showing in
1020ab369468265cd29a90b385a6e950eda3da16636dEric Dong                   current form.
1021ab369468265cd29a90b385a6e950eda3da16636dEric Dong                   The value is the line number between the new selected menu and the
1022ab369468265cd29a90b385a6e950eda3da16636dEric Dong                   current select menu, not include the new selected menu.
10237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
10257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongINTN
10267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongMoveToNextStatement (
10277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN     BOOLEAN                   GoUp,
10287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN OUT LIST_ENTRY                **CurrentPosition,
1029ab369468265cd29a90b385a6e950eda3da16636dEric Dong  IN     UINTN                     GapToTop,
1030ab369468265cd29a90b385a6e950eda3da16636dEric Dong  IN     BOOLEAN                   FindInForm
10317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
10327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
10337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  INTN             Distance;
10347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY       *Pos;
10357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_MENU_OPTION   *NextMenuOption;
10367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_MENU_OPTION   *PreMenuOption;
10377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Distance      = 0;
10397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Pos           = *CurrentPosition;
1040ab369468265cd29a90b385a6e950eda3da16636dEric Dong
1041ab369468265cd29a90b385a6e950eda3da16636dEric Dong  if (Pos == &gMenuOption) {
1042ab369468265cd29a90b385a6e950eda3da16636dEric Dong    return -1;
1043ab369468265cd29a90b385a6e950eda3da16636dEric Dong  }
1044ab369468265cd29a90b385a6e950eda3da16636dEric Dong
10457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  PreMenuOption = MENU_OPTION_FROM_LINK (Pos);
10467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  while (TRUE) {
10487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    NextMenuOption = MENU_OPTION_FROM_LINK (Pos);
10497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
10507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // NextMenuOption->Row == 0 means this menu has not calculate
10517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // the NextMenuOption->Skip value yet, just calculate here.
10527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
10537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (NextMenuOption->Row == 0) {
10547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      UpdateOptionSkipLines (NextMenuOption);
10557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
10567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1057ab369468265cd29a90b385a6e950eda3da16636dEric Dong    if (IsSelectable (NextMenuOption)) {
1058ab369468265cd29a90b385a6e950eda3da16636dEric Dong      break;
10597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
10607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1061ab369468265cd29a90b385a6e950eda3da16636dEric Dong    //
1062ab369468265cd29a90b385a6e950eda3da16636dEric Dong    // In this case, still can't find the selectable menu,
1063ab369468265cd29a90b385a6e950eda3da16636dEric Dong    // return the first one beyond the showing form.
1064ab369468265cd29a90b385a6e950eda3da16636dEric Dong    //
1065ab369468265cd29a90b385a6e950eda3da16636dEric Dong    if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {
1066ab369468265cd29a90b385a6e950eda3da16636dEric Dong      if (FindInForm) {
1067ab369468265cd29a90b385a6e950eda3da16636dEric Dong        NextMenuOption = PreMenuOption;
1068ab369468265cd29a90b385a6e950eda3da16636dEric Dong      }
10697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
10707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
10717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1072ab369468265cd29a90b385a6e950eda3da16636dEric Dong    Distance += NextMenuOption->Skip;
1073ab369468265cd29a90b385a6e950eda3da16636dEric Dong
10747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
10757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Arrive at begin of the menu list.
10767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
10777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if ((GoUp ? Pos->BackLink : Pos->ForwardLink) == &gMenuOption) {
10787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Distance = -1;
10797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
10807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
10817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Pos = (GoUp ? Pos->BackLink : Pos->ForwardLink);
1083ab369468265cd29a90b385a6e950eda3da16636dEric Dong    PreMenuOption = NextMenuOption;
10847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
10857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  *CurrentPosition = &NextMenuOption->Link;
10877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return Distance;
10887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
10897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
10927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Process option string for date/time opcode.
10937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  MenuOption              Menu option point to date/time.
10957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  OptionString            Option string input for process.
10967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  AddOptCol               Whether need to update MenuOption->OptCol.
10977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
10997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
11007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongProcessStringForDateTime (
11017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_MENU_OPTION                  *MenuOption,
11027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16                          *OptionString,
11037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BOOLEAN                         AddOptCol
11047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
11057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
11067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN Index;
11077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN Count;
11087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FORM_DISPLAY_ENGINE_STATEMENT          *Statement;
11097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_IFR_DATE                           *Date;
11107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_IFR_TIME                           *Time;
11117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT (MenuOption != NULL && OptionString != NULL);
11137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Statement = MenuOption->ThisTag;
11157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Date      = NULL;
11167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Time      = NULL;
11177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP) {
11187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Date = (EFI_IFR_DATE *) Statement->OpCode;
11197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else if (Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
11207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Time = (EFI_IFR_TIME *) Statement->OpCode;
11217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
11227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
11247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // If leading spaces on OptionString - remove the spaces
11257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
11267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  for (Index = 0; OptionString[Index] == L' '; Index++) {
11277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
11287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Base on the blockspace to get the option column info.
11297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
11307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (AddOptCol) {
11317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption->OptCol++;
11327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
11337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
11347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  for (Count = 0; OptionString[Index] != CHAR_NULL; Index++) {
11367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    OptionString[Count] = OptionString[Index];
11377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Count++;
11387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
11397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OptionString[Count] = CHAR_NULL;
11407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
11427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Enable to suppress field in the opcode base on the flag.
11437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
11447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP) {
11457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
11467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // OptionString format is: <**:  **: ****>
11477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //                        |month|day|year|
11487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //                          4     3    5
11497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
11507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if ((Date->Flags & EFI_QF_DATE_MONTH_SUPPRESS) && (MenuOption->Sequence == 0)) {
11517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
11527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // At this point, only "<**:" in the optionstring.
11537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Clean the day's ** field, after clean, the format is "<  :"
11547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
11557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      SetUnicodeMem (&OptionString[1], 2, L' ');
11567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else if ((Date->Flags & EFI_QF_DATE_DAY_SUPPRESS) && (MenuOption->Sequence == 1)) {
11577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
11587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // At this point, only "**:" in the optionstring.
11597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Clean the month's "**" field, after clean, the format is "  :"
11607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
11617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      SetUnicodeMem (&OptionString[0], 2, L' ');
11627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else if ((Date->Flags & EFI_QF_DATE_YEAR_SUPPRESS) && (MenuOption->Sequence == 2)) {
11637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
11647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // At this point, only "****>" in the optionstring.
11657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Clean the year's "****" field, after clean, the format is "  >"
11667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
11677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      SetUnicodeMem (&OptionString[0], 4, L' ');
11687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
11697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else if (Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
11707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
11717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // OptionString format is: <**:  **:    **>
11727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //                        |hour|minute|second|
11737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //                          4     3      3
11747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
11757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if ((Time->Flags & QF_TIME_HOUR_SUPPRESS) && (MenuOption->Sequence == 0)) {
11767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
11777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // At this point, only "<**:" in the optionstring.
11787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Clean the hour's ** field, after clean, the format is "<  :"
11797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
11807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      SetUnicodeMem (&OptionString[1], 2, L' ');
11817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else if ((Time->Flags & QF_TIME_MINUTE_SUPPRESS) && (MenuOption->Sequence == 1)) {
11827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
11837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // At this point, only "**:" in the optionstring.
11847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Clean the minute's "**" field, after clean, the format is "  :"
11857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
11867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      SetUnicodeMem (&OptionString[0], 2, L' ');
11877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else if ((Time->Flags & QF_TIME_SECOND_SUPPRESS) && (MenuOption->Sequence == 2)) {
11887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
11897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // At this point, only "**>" in the optionstring.
11907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Clean the second's "**" field, after clean, the format is "  >"
11917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
11927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      SetUnicodeMem (&OptionString[0], 2, L' ');
11937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
11947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
11957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
11967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
11997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Adjust Data and Time position accordingly.
12007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Data format :      [01/02/2004]      [11:22:33]
12017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Line number :        0  0    1         0  0  1
12027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  This is an internal function.
12047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  DirectionUp            the up or down direction. False is down. True is
12067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                                 up.
12077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  CurrentPosition        Current position. On return: Point to the last
12087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                                 Option (Year or Second) if up; Point to the first
12097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                                 Option (Month or Hour) if down.
12107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return Return line number to pad. It is possible that we stand on a zero-advance
12127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return data or time opcode, so pad one line when we judge if we are going to scroll outside.
12137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
12157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUINTN
12167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongAdjustDateAndTimePosition (
12177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN     BOOLEAN                     DirectionUp,
12187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN OUT LIST_ENTRY                  **CurrentPosition
12197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
12207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
12217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN           Count;
12227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY      *NewPosition;
12237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_MENU_OPTION  *MenuOption;
12247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN           PadLineNumber;
12257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  PadLineNumber = 0;
12277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  NewPosition   = *CurrentPosition;
12287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  MenuOption    = MENU_OPTION_FROM_LINK (NewPosition);
12297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) ||
12317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)) {
12327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
12337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Calculate the distance from current position to the last Date/Time MenuOption
12347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
12357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Count = 0;
12367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    while (MenuOption->Skip == 0) {
12377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Count++;
12387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      NewPosition   = NewPosition->ForwardLink;
12397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MenuOption    = MENU_OPTION_FROM_LINK (NewPosition);
12407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      PadLineNumber = 1;
12417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
12427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    NewPosition = *CurrentPosition;
12447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (DirectionUp) {
12457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
12467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Since the behavior of hitting the up arrow on a Date/Time MenuOption is intended
12477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // to be one that back to the previous set of MenuOptions, we need to advance to the first
12487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Date/Time MenuOption and leave the remaining logic in CfUiUp intact so the appropriate
12497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // checking can be done.
12507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
12517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      while (Count++ < 2) {
12527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        NewPosition = NewPosition->BackLink;
12537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
12547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
12557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
12567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Since the behavior of hitting the down arrow on a Date/Time MenuOption is intended
12577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // to be one that progresses to the next set of MenuOptions, we need to advance to the last
12587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Date/Time MenuOption and leave the remaining logic in CfUiDown intact so the appropriate
12597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // checking can be done.
12607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
12617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      while (Count-- > 0) {
12627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        NewPosition = NewPosition->ForwardLink;
12637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
12647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
12657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *CurrentPosition = NewPosition;
12677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
12687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return PadLineNumber;
12707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
12717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
12737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Get step info from numeric opcode.
12747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param[in] OpCode     The input numeric op code.
12767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return step info for this opcode.
12787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
12797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUINT64
12807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongGetFieldFromNum (
12817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  EFI_IFR_OP_HEADER     *OpCode
12827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
12837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
12847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_IFR_NUMERIC       *NumericOp;
12857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT64                Step;
12867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  NumericOp = (EFI_IFR_NUMERIC *) OpCode;
12887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  switch (NumericOp->Flags & EFI_IFR_NUMERIC_SIZE) {
12907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_NUMERIC_SIZE_1:
12917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Step    = NumericOp->data.u8.Step;
12927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
12937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_NUMERIC_SIZE_2:
12957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Step    = NumericOp->data.u16.Step;
12967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
12977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_NUMERIC_SIZE_4:
12997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Step    = NumericOp->data.u32.Step;
13007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
13017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_NUMERIC_SIZE_8:
13037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Step    = NumericOp->data.u64.Step;
13047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
13057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  default:
13077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Step = 0;
13087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
13097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
13107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return Step;
13127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
13137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
13157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Find the registered HotKey based on KeyData.
13167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param[in] KeyData     A pointer to a buffer that describes the keystroke
13187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                         information for the hot key.
13197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return The registered HotKey context. If no found, NULL will return.
13217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
13227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongBROWSER_HOT_KEY *
13237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongGetHotKeyFromRegisterList (
13247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN EFI_INPUT_KEY *KeyData
13257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
13267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
13277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY       *Link;
13287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BROWSER_HOT_KEY  *HotKey;
13297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Link = GetFirstNode (&gFormData->HotKeyListHead);
13317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  while (!IsNull (&gFormData->HotKeyListHead, Link)) {
13327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);
13337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (HotKey->KeyData->ScanCode == KeyData->ScanCode) {
13357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      return HotKey;
13367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
13377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Link = GetNextNode (&gFormData->HotKeyListHead, Link);
13397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
13407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return NULL;
13427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
13437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
13467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Determine if the menu is the last menu that can be selected.
13477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  This is an internal function.
13497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Direction              The scroll direction. False is down. True is up.
13517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  CurrentPos             The current focus.
13527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return FALSE -- the menu isn't the last menu that can be selected.
13547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return TRUE  -- the menu is the last menu that can be selected.
13557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
13577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongBOOLEAN
13587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongValueIsScroll (
13597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  BOOLEAN                     Direction,
13607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  LIST_ENTRY                  *CurrentPos
13617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
13627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
13637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY      *Temp;
13647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Temp = Direction ? CurrentPos->BackLink : CurrentPos->ForwardLink;
13667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (Temp == &gMenuOption) {
13687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return TRUE;
13697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
13707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return FALSE;
13727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
13737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
13757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Wait for a given event to fire, or for an optional timeout to expire.
13767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Event                  The event to wait for
13787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval UI_EVENT_TYPE          The type of the event which is trigged.
13807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
13827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUI_EVENT_TYPE
13837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUiWaitForEvent (
13847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN EFI_EVENT                Event
13857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
13867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
13877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_STATUS  Status;
13887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN       Index;
13897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN       EventNum;
13907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT64      Timeout;
13917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_EVENT   TimerEvent;
13927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_EVENT   WaitList[3];
13937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_EVENT_TYPE  EventType;
13947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  TimerEvent = NULL;
13967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Timeout    = FormExitTimeout(gFormData);
13977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (Timeout != 0) {
13997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);
14007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
14027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Set the timer event
14037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
14047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    gBS->SetTimer (
14057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          TimerEvent,
14067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          TimerRelative,
14077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Timeout
14087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          );
14097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
14107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  WaitList[0] = Event;
14127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EventNum    = 1;
14137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (gFormData->FormRefreshEvent != NULL) {
14147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    WaitList[EventNum] = gFormData->FormRefreshEvent;
14157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    EventNum ++;
14167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
14177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (Timeout != 0) {
14197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    WaitList[EventNum] = TimerEvent;
14207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    EventNum ++;
14217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
14227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Status = gBS->WaitForEvent (EventNum, WaitList, &Index);
14247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT_EFI_ERROR (Status);
14257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  switch (Index) {
14277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case 0:
14287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong   EventType = UIEventKey;
14297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong   break;
14307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case 1:
14327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (gFormData->FormRefreshEvent != NULL) {
14337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      EventType = UIEventDriver;
14347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
14357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT (Timeout != 0 && EventNum == 2);
14367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      EventType = UIEventTimeOut;
14377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
14387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
14397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  default:
14417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ASSERT (Index == 2 && EventNum == 3);
14427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    EventType = UIEventTimeOut;
14437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
14447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
14457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (Timeout != 0) {
14477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    gBS->CloseEvent (TimerEvent);
14487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
14497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return EventType;
14517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
14527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
14547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Get question id info from the input opcode header.
14557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  OpCode                 The input opcode header pointer.
14577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval                        The question id for this opcode.
14597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
14617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFI_QUESTION_ID
14627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongGetQuestionIdInfo (
14637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN   EFI_IFR_OP_HEADER     *OpCode
14647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
14657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
14667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_IFR_QUESTION_HEADER   *QuestionHeader;
14677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (OpCode->Length < sizeof (EFI_IFR_OP_HEADER) + sizeof (EFI_IFR_QUESTION_HEADER)) {
14697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return 0;
14707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
14717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  QuestionHeader = (EFI_IFR_QUESTION_HEADER *)((UINT8 *) OpCode + sizeof(EFI_IFR_OP_HEADER));
14737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return QuestionHeader->QuestionId;
14757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
14767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
1477ab369468265cd29a90b385a6e950eda3da16636dEric Dong
1478ab369468265cd29a90b385a6e950eda3da16636dEric Dong/**
1479ab369468265cd29a90b385a6e950eda3da16636dEric Dong  Find the top of screen menu base on the current menu.
1480ab369468265cd29a90b385a6e950eda3da16636dEric Dong
1481ab369468265cd29a90b385a6e950eda3da16636dEric Dong  @param  CurPos                 Current input menu.
1482ab369468265cd29a90b385a6e950eda3da16636dEric Dong  @param  Rows                   Totol screen rows.
1483ab369468265cd29a90b385a6e950eda3da16636dEric Dong  @param  SkipValue              SkipValue for this new form.
1484ab369468265cd29a90b385a6e950eda3da16636dEric Dong
1485ab369468265cd29a90b385a6e950eda3da16636dEric Dong  @retval TopOfScreen            Top of screen menu for the new form.
1486ab369468265cd29a90b385a6e950eda3da16636dEric Dong
1487ab369468265cd29a90b385a6e950eda3da16636dEric Dong**/
1488ab369468265cd29a90b385a6e950eda3da16636dEric DongLIST_ENTRY *
1489ab369468265cd29a90b385a6e950eda3da16636dEric DongFindTopOfScreenMenu (
1490ab369468265cd29a90b385a6e950eda3da16636dEric Dong  IN  LIST_ENTRY                      *CurPos,
1491ab369468265cd29a90b385a6e950eda3da16636dEric Dong  IN  UINTN                           Rows,
1492ab369468265cd29a90b385a6e950eda3da16636dEric Dong  OUT UINTN                           *SkipValue
1493ab369468265cd29a90b385a6e950eda3da16636dEric Dong  )
1494ab369468265cd29a90b385a6e950eda3da16636dEric Dong{
1495ab369468265cd29a90b385a6e950eda3da16636dEric Dong  LIST_ENTRY        *Link;
1496ab369468265cd29a90b385a6e950eda3da16636dEric Dong  LIST_ENTRY        *TopOfScreen;
1497ab369468265cd29a90b385a6e950eda3da16636dEric Dong  UI_MENU_OPTION    *PreviousMenuOption;
1498ab369468265cd29a90b385a6e950eda3da16636dEric Dong
1499ab369468265cd29a90b385a6e950eda3da16636dEric Dong  Link = CurPos;
1500ab369468265cd29a90b385a6e950eda3da16636dEric Dong  PreviousMenuOption = NULL;
1501ab369468265cd29a90b385a6e950eda3da16636dEric Dong
1502ab369468265cd29a90b385a6e950eda3da16636dEric Dong  while (Link->BackLink != &gMenuOption) {
1503ab369468265cd29a90b385a6e950eda3da16636dEric Dong    Link = Link->BackLink;
1504ab369468265cd29a90b385a6e950eda3da16636dEric Dong    PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);
1505ab369468265cd29a90b385a6e950eda3da16636dEric Dong    if (PreviousMenuOption->Row == 0) {
1506ab369468265cd29a90b385a6e950eda3da16636dEric Dong      UpdateOptionSkipLines (PreviousMenuOption);
1507ab369468265cd29a90b385a6e950eda3da16636dEric Dong    }
1508ab369468265cd29a90b385a6e950eda3da16636dEric Dong    if (Rows <= PreviousMenuOption->Skip) {
1509ab369468265cd29a90b385a6e950eda3da16636dEric Dong      break;
1510ab369468265cd29a90b385a6e950eda3da16636dEric Dong    }
1511ab369468265cd29a90b385a6e950eda3da16636dEric Dong    Rows = Rows - PreviousMenuOption->Skip;
1512ab369468265cd29a90b385a6e950eda3da16636dEric Dong  }
1513ab369468265cd29a90b385a6e950eda3da16636dEric Dong
1514ab369468265cd29a90b385a6e950eda3da16636dEric Dong  if (Link->BackLink == &gMenuOption) {
1515ab369468265cd29a90b385a6e950eda3da16636dEric Dong    TopOfScreen = gMenuOption.ForwardLink;
1516ab369468265cd29a90b385a6e950eda3da16636dEric Dong    if (PreviousMenuOption != NULL && Rows < PreviousMenuOption->Skip) {
1517ab369468265cd29a90b385a6e950eda3da16636dEric Dong      *SkipValue = PreviousMenuOption->Skip - Rows;
1518ab369468265cd29a90b385a6e950eda3da16636dEric Dong    } else {
1519ab369468265cd29a90b385a6e950eda3da16636dEric Dong      *SkipValue = 0;
1520ab369468265cd29a90b385a6e950eda3da16636dEric Dong    }
1521ab369468265cd29a90b385a6e950eda3da16636dEric Dong  } else {
1522ab369468265cd29a90b385a6e950eda3da16636dEric Dong    TopOfScreen = Link;
1523ab369468265cd29a90b385a6e950eda3da16636dEric Dong    *SkipValue = PreviousMenuOption->Skip - Rows;
1524ab369468265cd29a90b385a6e950eda3da16636dEric Dong  }
1525ab369468265cd29a90b385a6e950eda3da16636dEric Dong
1526ab369468265cd29a90b385a6e950eda3da16636dEric Dong  return TopOfScreen;
1527ab369468265cd29a90b385a6e950eda3da16636dEric Dong}
1528ab369468265cd29a90b385a6e950eda3da16636dEric Dong
15297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
153042645c3dcf0488c616422dcdfd1596939223f432Eric Dong  Get the index info for this opcode.
153142645c3dcf0488c616422dcdfd1596939223f432Eric Dong
153242645c3dcf0488c616422dcdfd1596939223f432Eric Dong  @param  OpCode      The input opcode for the statement.
153342645c3dcf0488c616422dcdfd1596939223f432Eric Dong
153442645c3dcf0488c616422dcdfd1596939223f432Eric Dong  @retval  The index of this statement.
153542645c3dcf0488c616422dcdfd1596939223f432Eric Dong
153642645c3dcf0488c616422dcdfd1596939223f432Eric Dong**/
153742645c3dcf0488c616422dcdfd1596939223f432Eric DongUINTN
153842645c3dcf0488c616422dcdfd1596939223f432Eric DongGetIndexInfoForOpcode (
153942645c3dcf0488c616422dcdfd1596939223f432Eric Dong  IN EFI_IFR_OP_HEADER  *OpCode
154042645c3dcf0488c616422dcdfd1596939223f432Eric Dong  )
154142645c3dcf0488c616422dcdfd1596939223f432Eric Dong{
154242645c3dcf0488c616422dcdfd1596939223f432Eric Dong  LIST_ENTRY                      *NewPos;
154342645c3dcf0488c616422dcdfd1596939223f432Eric Dong  UI_MENU_OPTION                  *MenuOption;
154442645c3dcf0488c616422dcdfd1596939223f432Eric Dong  UINTN                           Index;
154542645c3dcf0488c616422dcdfd1596939223f432Eric Dong
154642645c3dcf0488c616422dcdfd1596939223f432Eric Dong  NewPos = gMenuOption.ForwardLink;
154742645c3dcf0488c616422dcdfd1596939223f432Eric Dong  Index  = 0;
154842645c3dcf0488c616422dcdfd1596939223f432Eric Dong
154942645c3dcf0488c616422dcdfd1596939223f432Eric Dong  for (NewPos = gMenuOption.ForwardLink; NewPos != &gMenuOption; NewPos = NewPos->ForwardLink){
155042645c3dcf0488c616422dcdfd1596939223f432Eric Dong    MenuOption = MENU_OPTION_FROM_LINK (NewPos);
155142645c3dcf0488c616422dcdfd1596939223f432Eric Dong
155242645c3dcf0488c616422dcdfd1596939223f432Eric Dong    if (CompareMem (MenuOption->ThisTag->OpCode, OpCode, OpCode->Length) == 0) {
155342645c3dcf0488c616422dcdfd1596939223f432Eric Dong      if (MenuOption->ThisTag->OpCode == OpCode) {
155442645c3dcf0488c616422dcdfd1596939223f432Eric Dong        return Index;
155542645c3dcf0488c616422dcdfd1596939223f432Eric Dong      }
155642645c3dcf0488c616422dcdfd1596939223f432Eric Dong
155742645c3dcf0488c616422dcdfd1596939223f432Eric Dong      Index ++;
155842645c3dcf0488c616422dcdfd1596939223f432Eric Dong    }
155942645c3dcf0488c616422dcdfd1596939223f432Eric Dong  }
156042645c3dcf0488c616422dcdfd1596939223f432Eric Dong
156142645c3dcf0488c616422dcdfd1596939223f432Eric Dong  return Index;
156242645c3dcf0488c616422dcdfd1596939223f432Eric Dong}
156342645c3dcf0488c616422dcdfd1596939223f432Eric Dong
156442645c3dcf0488c616422dcdfd1596939223f432Eric Dong/**
156542645c3dcf0488c616422dcdfd1596939223f432Eric Dong  Is this the saved highlight statement.
156642645c3dcf0488c616422dcdfd1596939223f432Eric Dong
156742645c3dcf0488c616422dcdfd1596939223f432Eric Dong  @param  HighLightedStatement      The input highlight statement.
156842645c3dcf0488c616422dcdfd1596939223f432Eric Dong
156942645c3dcf0488c616422dcdfd1596939223f432Eric Dong  @retval  TRUE   This is the highlight statement.
157042645c3dcf0488c616422dcdfd1596939223f432Eric Dong  @retval  FALSE  This is not the highlight statement.
157142645c3dcf0488c616422dcdfd1596939223f432Eric Dong
157242645c3dcf0488c616422dcdfd1596939223f432Eric Dong**/
157342645c3dcf0488c616422dcdfd1596939223f432Eric DongBOOLEAN
157442645c3dcf0488c616422dcdfd1596939223f432Eric DongIsSavedHighlightStatement (
157542645c3dcf0488c616422dcdfd1596939223f432Eric Dong  IN FORM_DISPLAY_ENGINE_STATEMENT  *HighLightedStatement
157642645c3dcf0488c616422dcdfd1596939223f432Eric Dong  )
157742645c3dcf0488c616422dcdfd1596939223f432Eric Dong{
157842645c3dcf0488c616422dcdfd1596939223f432Eric Dong  if ((gFormData->HiiHandle == gHighligthMenuInfo.HiiHandle) &&
157942645c3dcf0488c616422dcdfd1596939223f432Eric Dong      (gFormData->FormId == gHighligthMenuInfo.FormId)) {
158042645c3dcf0488c616422dcdfd1596939223f432Eric Dong    if (gHighligthMenuInfo.HLTQuestionId != 0) {
15812e097165e9ad2bfc373b2a8f1126267f14ca26a3Eric Dong      return (BOOLEAN) (gHighligthMenuInfo.HLTQuestionId == GetQuestionIdInfo (HighLightedStatement->OpCode));
158242645c3dcf0488c616422dcdfd1596939223f432Eric Dong    } else {
158342645c3dcf0488c616422dcdfd1596939223f432Eric Dong      if (CompareMem (gHighligthMenuInfo.HLTOpCode, HighLightedStatement->OpCode, gHighligthMenuInfo.HLTOpCode->Length) == 0) {
158442645c3dcf0488c616422dcdfd1596939223f432Eric Dong        if (gHighligthMenuInfo.HLTIndex == 0 || gHighligthMenuInfo.HLTIndex == GetIndexInfoForOpcode(HighLightedStatement->OpCode)) {
158542645c3dcf0488c616422dcdfd1596939223f432Eric Dong          return TRUE;
158642645c3dcf0488c616422dcdfd1596939223f432Eric Dong        } else {
158742645c3dcf0488c616422dcdfd1596939223f432Eric Dong          return FALSE;
158842645c3dcf0488c616422dcdfd1596939223f432Eric Dong        }
158942645c3dcf0488c616422dcdfd1596939223f432Eric Dong      }
159042645c3dcf0488c616422dcdfd1596939223f432Eric Dong    }
159142645c3dcf0488c616422dcdfd1596939223f432Eric Dong  }
159242645c3dcf0488c616422dcdfd1596939223f432Eric Dong
159342645c3dcf0488c616422dcdfd1596939223f432Eric Dong  return FALSE;
159442645c3dcf0488c616422dcdfd1596939223f432Eric Dong}
159542645c3dcf0488c616422dcdfd1596939223f432Eric Dong
159642645c3dcf0488c616422dcdfd1596939223f432Eric Dong/**
159742645c3dcf0488c616422dcdfd1596939223f432Eric Dong  Is this the highlight menu.
159842645c3dcf0488c616422dcdfd1596939223f432Eric Dong
159942645c3dcf0488c616422dcdfd1596939223f432Eric Dong  @param  MenuOption      The input Menu option.
160042645c3dcf0488c616422dcdfd1596939223f432Eric Dong
160142645c3dcf0488c616422dcdfd1596939223f432Eric Dong  @retval  TRUE   This is the highlight menu option.
160242645c3dcf0488c616422dcdfd1596939223f432Eric Dong  @retval  FALSE  This is not the highlight menu option.
160342645c3dcf0488c616422dcdfd1596939223f432Eric Dong
160442645c3dcf0488c616422dcdfd1596939223f432Eric Dong**/
160542645c3dcf0488c616422dcdfd1596939223f432Eric DongBOOLEAN
160642645c3dcf0488c616422dcdfd1596939223f432Eric DongIsHighLightMenuOption (
160742645c3dcf0488c616422dcdfd1596939223f432Eric Dong  IN UI_MENU_OPTION     *MenuOption
160842645c3dcf0488c616422dcdfd1596939223f432Eric Dong  )
160942645c3dcf0488c616422dcdfd1596939223f432Eric Dong{
161042645c3dcf0488c616422dcdfd1596939223f432Eric Dong  if (gHighligthMenuInfo.HLTQuestionId != 0) {
161142645c3dcf0488c616422dcdfd1596939223f432Eric Dong    if (GetQuestionIdInfo(MenuOption->ThisTag->OpCode) == gHighligthMenuInfo.HLTQuestionId) {
16122e097165e9ad2bfc373b2a8f1126267f14ca26a3Eric Dong      return (BOOLEAN) (MenuOption->Sequence == gHighligthMenuInfo.HLTSequence);
161342645c3dcf0488c616422dcdfd1596939223f432Eric Dong    }
161442645c3dcf0488c616422dcdfd1596939223f432Eric Dong  } else {
161542645c3dcf0488c616422dcdfd1596939223f432Eric Dong    if(CompareMem (gHighligthMenuInfo.HLTOpCode, MenuOption->ThisTag->OpCode, gHighligthMenuInfo.HLTOpCode->Length) == 0) {
161642645c3dcf0488c616422dcdfd1596939223f432Eric Dong      if (gHighligthMenuInfo.HLTIndex == 0 || gHighligthMenuInfo.HLTIndex == GetIndexInfoForOpcode(MenuOption->ThisTag->OpCode)) {
16172e097165e9ad2bfc373b2a8f1126267f14ca26a3Eric Dong        return (BOOLEAN) (MenuOption->Sequence == gHighligthMenuInfo.HLTSequence);
161842645c3dcf0488c616422dcdfd1596939223f432Eric Dong      } else {
161942645c3dcf0488c616422dcdfd1596939223f432Eric Dong        return FALSE;
162042645c3dcf0488c616422dcdfd1596939223f432Eric Dong      }
162142645c3dcf0488c616422dcdfd1596939223f432Eric Dong    }
162242645c3dcf0488c616422dcdfd1596939223f432Eric Dong  }
162342645c3dcf0488c616422dcdfd1596939223f432Eric Dong
162442645c3dcf0488c616422dcdfd1596939223f432Eric Dong  return FALSE;
162542645c3dcf0488c616422dcdfd1596939223f432Eric Dong}
162642645c3dcf0488c616422dcdfd1596939223f432Eric Dong
162742645c3dcf0488c616422dcdfd1596939223f432Eric Dong/**
162842645c3dcf0488c616422dcdfd1596939223f432Eric Dong  Find the highlight menu.
162942645c3dcf0488c616422dcdfd1596939223f432Eric Dong
163042645c3dcf0488c616422dcdfd1596939223f432Eric Dong  If the input is NULL, base on the record highlight info in
163142645c3dcf0488c616422dcdfd1596939223f432Eric Dong  gHighligthMenuInfo to find the last highlight menu.
163242645c3dcf0488c616422dcdfd1596939223f432Eric Dong
163342645c3dcf0488c616422dcdfd1596939223f432Eric Dong  @param  HighLightedStatement      The input highlight statement.
163442645c3dcf0488c616422dcdfd1596939223f432Eric Dong
163542645c3dcf0488c616422dcdfd1596939223f432Eric Dong  @retval  The highlight menu index.
163642645c3dcf0488c616422dcdfd1596939223f432Eric Dong
163742645c3dcf0488c616422dcdfd1596939223f432Eric Dong**/
163842645c3dcf0488c616422dcdfd1596939223f432Eric DongLIST_ENTRY *
163942645c3dcf0488c616422dcdfd1596939223f432Eric DongFindHighLightMenuOption (
164042645c3dcf0488c616422dcdfd1596939223f432Eric Dong IN FORM_DISPLAY_ENGINE_STATEMENT  *HighLightedStatement
164142645c3dcf0488c616422dcdfd1596939223f432Eric Dong )
164242645c3dcf0488c616422dcdfd1596939223f432Eric Dong{
164342645c3dcf0488c616422dcdfd1596939223f432Eric Dong  LIST_ENTRY                      *NewPos;
164442645c3dcf0488c616422dcdfd1596939223f432Eric Dong  UI_MENU_OPTION                  *MenuOption;
164542645c3dcf0488c616422dcdfd1596939223f432Eric Dong
164642645c3dcf0488c616422dcdfd1596939223f432Eric Dong  NewPos = gMenuOption.ForwardLink;
164742645c3dcf0488c616422dcdfd1596939223f432Eric Dong  MenuOption = MENU_OPTION_FROM_LINK (NewPos);
164842645c3dcf0488c616422dcdfd1596939223f432Eric Dong
164942645c3dcf0488c616422dcdfd1596939223f432Eric Dong  if (HighLightedStatement != NULL) {
165042645c3dcf0488c616422dcdfd1596939223f432Eric Dong    while (MenuOption->ThisTag != HighLightedStatement) {
165142645c3dcf0488c616422dcdfd1596939223f432Eric Dong      NewPos     = NewPos->ForwardLink;
165242645c3dcf0488c616422dcdfd1596939223f432Eric Dong      if (NewPos == &gMenuOption) {
165342645c3dcf0488c616422dcdfd1596939223f432Eric Dong        //
165442645c3dcf0488c616422dcdfd1596939223f432Eric Dong        // Not Found it, break
165542645c3dcf0488c616422dcdfd1596939223f432Eric Dong        //
165642645c3dcf0488c616422dcdfd1596939223f432Eric Dong        break;
165742645c3dcf0488c616422dcdfd1596939223f432Eric Dong      }
165842645c3dcf0488c616422dcdfd1596939223f432Eric Dong      MenuOption = MENU_OPTION_FROM_LINK (NewPos);
165942645c3dcf0488c616422dcdfd1596939223f432Eric Dong    }
166042645c3dcf0488c616422dcdfd1596939223f432Eric Dong
166142645c3dcf0488c616422dcdfd1596939223f432Eric Dong    //
166242645c3dcf0488c616422dcdfd1596939223f432Eric Dong    // Must find the highlight statement.
166342645c3dcf0488c616422dcdfd1596939223f432Eric Dong    //
166442645c3dcf0488c616422dcdfd1596939223f432Eric Dong    ASSERT (NewPos != &gMenuOption);
166542645c3dcf0488c616422dcdfd1596939223f432Eric Dong
166642645c3dcf0488c616422dcdfd1596939223f432Eric Dong  } else {
166742645c3dcf0488c616422dcdfd1596939223f432Eric Dong    while (!IsHighLightMenuOption (MenuOption)) {
166842645c3dcf0488c616422dcdfd1596939223f432Eric Dong      NewPos     = NewPos->ForwardLink;
166942645c3dcf0488c616422dcdfd1596939223f432Eric Dong      if (NewPos == &gMenuOption) {
167042645c3dcf0488c616422dcdfd1596939223f432Eric Dong        //
167142645c3dcf0488c616422dcdfd1596939223f432Eric Dong        // Not Found it, break
167242645c3dcf0488c616422dcdfd1596939223f432Eric Dong        //
167342645c3dcf0488c616422dcdfd1596939223f432Eric Dong        break;
167442645c3dcf0488c616422dcdfd1596939223f432Eric Dong      }
167542645c3dcf0488c616422dcdfd1596939223f432Eric Dong      MenuOption = MENU_OPTION_FROM_LINK (NewPos);
167642645c3dcf0488c616422dcdfd1596939223f432Eric Dong    }
167742645c3dcf0488c616422dcdfd1596939223f432Eric Dong
167842645c3dcf0488c616422dcdfd1596939223f432Eric Dong    //
167942645c3dcf0488c616422dcdfd1596939223f432Eric Dong    // Highlight statement has disappear (suppressed/disableed)
168042645c3dcf0488c616422dcdfd1596939223f432Eric Dong    //
168142645c3dcf0488c616422dcdfd1596939223f432Eric Dong    if (NewPos == &gMenuOption) {
168242645c3dcf0488c616422dcdfd1596939223f432Eric Dong      NewPos = NULL;
168342645c3dcf0488c616422dcdfd1596939223f432Eric Dong    }
168442645c3dcf0488c616422dcdfd1596939223f432Eric Dong  }
168542645c3dcf0488c616422dcdfd1596939223f432Eric Dong
168642645c3dcf0488c616422dcdfd1596939223f432Eric Dong  return NewPos;
168742645c3dcf0488c616422dcdfd1596939223f432Eric Dong}
168842645c3dcf0488c616422dcdfd1596939223f432Eric Dong
168942645c3dcf0488c616422dcdfd1596939223f432Eric Dong/**
169042645c3dcf0488c616422dcdfd1596939223f432Eric Dong  Is this the Top of screen menu.
169142645c3dcf0488c616422dcdfd1596939223f432Eric Dong
169242645c3dcf0488c616422dcdfd1596939223f432Eric Dong  @param  MenuOption      The input Menu option.
169342645c3dcf0488c616422dcdfd1596939223f432Eric Dong
169442645c3dcf0488c616422dcdfd1596939223f432Eric Dong  @retval  TRUE   This is the Top of screen menu option.
169542645c3dcf0488c616422dcdfd1596939223f432Eric Dong  @retval  FALSE  This is not the Top of screen menu option.
169642645c3dcf0488c616422dcdfd1596939223f432Eric Dong
169742645c3dcf0488c616422dcdfd1596939223f432Eric Dong**/
169842645c3dcf0488c616422dcdfd1596939223f432Eric DongBOOLEAN
169942645c3dcf0488c616422dcdfd1596939223f432Eric DongIsTopOfScreeMenuOption (
170042645c3dcf0488c616422dcdfd1596939223f432Eric Dong  IN UI_MENU_OPTION     *MenuOption
170142645c3dcf0488c616422dcdfd1596939223f432Eric Dong  )
170242645c3dcf0488c616422dcdfd1596939223f432Eric Dong{
170342645c3dcf0488c616422dcdfd1596939223f432Eric Dong  if (gHighligthMenuInfo.TOSQuestionId != 0) {
17042e097165e9ad2bfc373b2a8f1126267f14ca26a3Eric Dong    return (BOOLEAN) (GetQuestionIdInfo(MenuOption->ThisTag->OpCode) == gHighligthMenuInfo.TOSQuestionId);
170542645c3dcf0488c616422dcdfd1596939223f432Eric Dong  }
170642645c3dcf0488c616422dcdfd1596939223f432Eric Dong
170742645c3dcf0488c616422dcdfd1596939223f432Eric Dong  if(CompareMem (gHighligthMenuInfo.TOSOpCode, MenuOption->ThisTag->OpCode, gHighligthMenuInfo.TOSOpCode->Length) == 0) {
170842645c3dcf0488c616422dcdfd1596939223f432Eric Dong    if (gHighligthMenuInfo.TOSIndex == 0 || gHighligthMenuInfo.TOSIndex == GetIndexInfoForOpcode(MenuOption->ThisTag->OpCode)) {
170942645c3dcf0488c616422dcdfd1596939223f432Eric Dong      return TRUE;
171042645c3dcf0488c616422dcdfd1596939223f432Eric Dong    } else {
171142645c3dcf0488c616422dcdfd1596939223f432Eric Dong      return FALSE;
171242645c3dcf0488c616422dcdfd1596939223f432Eric Dong    }
171342645c3dcf0488c616422dcdfd1596939223f432Eric Dong  }
171442645c3dcf0488c616422dcdfd1596939223f432Eric Dong
171542645c3dcf0488c616422dcdfd1596939223f432Eric Dong  return FALSE;
171642645c3dcf0488c616422dcdfd1596939223f432Eric Dong}
171742645c3dcf0488c616422dcdfd1596939223f432Eric Dong
171842645c3dcf0488c616422dcdfd1596939223f432Eric Dong/**
171942645c3dcf0488c616422dcdfd1596939223f432Eric Dong  Find the Top of screen menu.
172042645c3dcf0488c616422dcdfd1596939223f432Eric Dong
172142645c3dcf0488c616422dcdfd1596939223f432Eric Dong  If the input is NULL, base on the record highlight info in
172242645c3dcf0488c616422dcdfd1596939223f432Eric Dong  gHighligthMenuInfo to find the last highlight menu.
172342645c3dcf0488c616422dcdfd1596939223f432Eric Dong
172442645c3dcf0488c616422dcdfd1596939223f432Eric Dong  @param  HighLightedStatement      The input highlight statement.
172542645c3dcf0488c616422dcdfd1596939223f432Eric Dong
172642645c3dcf0488c616422dcdfd1596939223f432Eric Dong  @retval  The highlight menu index.
172742645c3dcf0488c616422dcdfd1596939223f432Eric Dong
172842645c3dcf0488c616422dcdfd1596939223f432Eric Dong**/
172942645c3dcf0488c616422dcdfd1596939223f432Eric DongLIST_ENTRY *
173042645c3dcf0488c616422dcdfd1596939223f432Eric DongFindTopOfScreenMenuOption (
173142645c3dcf0488c616422dcdfd1596939223f432Eric Dong VOID
173242645c3dcf0488c616422dcdfd1596939223f432Eric Dong )
173342645c3dcf0488c616422dcdfd1596939223f432Eric Dong{
173442645c3dcf0488c616422dcdfd1596939223f432Eric Dong  LIST_ENTRY                      *NewPos;
173542645c3dcf0488c616422dcdfd1596939223f432Eric Dong  UI_MENU_OPTION                  *MenuOption;
173642645c3dcf0488c616422dcdfd1596939223f432Eric Dong
173742645c3dcf0488c616422dcdfd1596939223f432Eric Dong  NewPos = gMenuOption.ForwardLink;
173842645c3dcf0488c616422dcdfd1596939223f432Eric Dong  MenuOption = MENU_OPTION_FROM_LINK (NewPos);
173942645c3dcf0488c616422dcdfd1596939223f432Eric Dong
174042645c3dcf0488c616422dcdfd1596939223f432Eric Dong  while (!IsTopOfScreeMenuOption(MenuOption)) {
174142645c3dcf0488c616422dcdfd1596939223f432Eric Dong    NewPos     = NewPos->ForwardLink;
174242645c3dcf0488c616422dcdfd1596939223f432Eric Dong    if (NewPos == &gMenuOption) {
174342645c3dcf0488c616422dcdfd1596939223f432Eric Dong      //
174442645c3dcf0488c616422dcdfd1596939223f432Eric Dong      // Not Found it, break
174542645c3dcf0488c616422dcdfd1596939223f432Eric Dong      //
174642645c3dcf0488c616422dcdfd1596939223f432Eric Dong      break;
174742645c3dcf0488c616422dcdfd1596939223f432Eric Dong    }
174842645c3dcf0488c616422dcdfd1596939223f432Eric Dong    MenuOption = MENU_OPTION_FROM_LINK (NewPos);
174942645c3dcf0488c616422dcdfd1596939223f432Eric Dong  }
175042645c3dcf0488c616422dcdfd1596939223f432Eric Dong
175142645c3dcf0488c616422dcdfd1596939223f432Eric Dong  //
175242645c3dcf0488c616422dcdfd1596939223f432Eric Dong  // Last time top of screen menu has disappeared.
175342645c3dcf0488c616422dcdfd1596939223f432Eric Dong  //
175442645c3dcf0488c616422dcdfd1596939223f432Eric Dong  if (NewPos == &gMenuOption) {
175542645c3dcf0488c616422dcdfd1596939223f432Eric Dong    NewPos = NULL;
175642645c3dcf0488c616422dcdfd1596939223f432Eric Dong  }
175742645c3dcf0488c616422dcdfd1596939223f432Eric Dong
175842645c3dcf0488c616422dcdfd1596939223f432Eric Dong  return NewPos;
175942645c3dcf0488c616422dcdfd1596939223f432Eric Dong}
176042645c3dcf0488c616422dcdfd1596939223f432Eric Dong
176142645c3dcf0488c616422dcdfd1596939223f432Eric Dong/**
17627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Find the first menu which will be show at the top.
17637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
17647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  FormData               The data info for this form.
17657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  TopOfScreen            The link_entry pointer to top menu.
17667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  HighlightMenu          The menu which will be highlight.
17677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  SkipValue              The skip value for the top menu.
17687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
17697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
17707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
17717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongFindTopMenu (
17727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  FORM_DISPLAY_ENGINE_FORM  *FormData,
17737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OUT LIST_ENTRY                **TopOfScreen,
17747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OUT LIST_ENTRY                **HighlightMenu,
1775ab369468265cd29a90b385a6e950eda3da16636dEric Dong  OUT UINTN                     *SkipValue
17767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
17777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
17787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           TopRow;
17797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           BottomRow;
178042645c3dcf0488c616422dcdfd1596939223f432Eric Dong  UI_MENU_OPTION                  *MenuOption;
1781ab369468265cd29a90b385a6e950eda3da16636dEric Dong  UINTN                           TmpValue;
17827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
17837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  TopRow    = gStatementDimensions.TopRow    + SCROLL_ARROW_HEIGHT;
17847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT;
1785b2f35637da091be37748203a5817a1c732c69e12Dandan Bi  //
1786b2f35637da091be37748203a5817a1c732c69e12Dandan Bi  // When option mismatch happens,there exist two cases,one is reenter the form, just like the if case below,
1787b2f35637da091be37748203a5817a1c732c69e12Dandan Bi  // and the other is exit current form and enter last form, it can be covered by the else case.
1788b2f35637da091be37748203a5817a1c732c69e12Dandan Bi  //
1789b2f35637da091be37748203a5817a1c732c69e12Dandan Bi  if (gMisMatch && gFormData->HiiHandle == gHighligthMenuInfo.HiiHandle && gFormData->FormId == gHighligthMenuInfo.FormId) {
179042645c3dcf0488c616422dcdfd1596939223f432Eric Dong    //
179142645c3dcf0488c616422dcdfd1596939223f432Eric Dong    // Reenter caused by option mismatch or auto exit caused by refresh form(refresh interval/guid),
179242645c3dcf0488c616422dcdfd1596939223f432Eric Dong    // base on the record highlight info to find the highlight menu.
179342645c3dcf0488c616422dcdfd1596939223f432Eric Dong    //
17947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
179542645c3dcf0488c616422dcdfd1596939223f432Eric Dong    *HighlightMenu = FindHighLightMenuOption(NULL);
179642645c3dcf0488c616422dcdfd1596939223f432Eric Dong    if (*HighlightMenu != NULL) {
17977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
179842645c3dcf0488c616422dcdfd1596939223f432Eric Dong      // Update skip info for this highlight menu.
17997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
180042645c3dcf0488c616422dcdfd1596939223f432Eric Dong      MenuOption = MENU_OPTION_FROM_LINK (*HighlightMenu);
180142645c3dcf0488c616422dcdfd1596939223f432Eric Dong      UpdateOptionSkipLines (MenuOption);
18027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
180342645c3dcf0488c616422dcdfd1596939223f432Eric Dong      //
180442645c3dcf0488c616422dcdfd1596939223f432Eric Dong      // Found the last time highlight menu.
180542645c3dcf0488c616422dcdfd1596939223f432Eric Dong      //
180642645c3dcf0488c616422dcdfd1596939223f432Eric Dong      *TopOfScreen = FindTopOfScreenMenuOption();
180742645c3dcf0488c616422dcdfd1596939223f432Eric Dong      if (*TopOfScreen != NULL) {
180842645c3dcf0488c616422dcdfd1596939223f432Eric Dong        //
180942645c3dcf0488c616422dcdfd1596939223f432Eric Dong        // Found the last time selectable top of screen menu.
181042645c3dcf0488c616422dcdfd1596939223f432Eric Dong        //
181142645c3dcf0488c616422dcdfd1596939223f432Eric Dong        AdjustDateAndTimePosition(TRUE, TopOfScreen);
181242645c3dcf0488c616422dcdfd1596939223f432Eric Dong        MenuOption = MENU_OPTION_FROM_LINK (*TopOfScreen);
181342645c3dcf0488c616422dcdfd1596939223f432Eric Dong        UpdateOptionSkipLines (MenuOption);
18147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
181542645c3dcf0488c616422dcdfd1596939223f432Eric Dong        *SkipValue = gHighligthMenuInfo.SkipValue;
181642645c3dcf0488c616422dcdfd1596939223f432Eric Dong      } else {
1817336c8e116b3e2e11dccdac163d0a85fc3c58fd3dEric Dong        //
181842645c3dcf0488c616422dcdfd1596939223f432Eric Dong        // Not found last time top of screen menu, so base on current highlight menu
181942645c3dcf0488c616422dcdfd1596939223f432Eric Dong        // to find the new top of screen menu.
182042645c3dcf0488c616422dcdfd1596939223f432Eric Dong        // Make the current highlight menu at the bottom of the form to calculate the
182142645c3dcf0488c616422dcdfd1596939223f432Eric Dong        // top of screen menu.
1822336c8e116b3e2e11dccdac163d0a85fc3c58fd3dEric Dong        //
182342645c3dcf0488c616422dcdfd1596939223f432Eric Dong        if (MenuOption->Skip >= BottomRow - TopRow) {
182442645c3dcf0488c616422dcdfd1596939223f432Eric Dong          *TopOfScreen = *HighlightMenu;
182542645c3dcf0488c616422dcdfd1596939223f432Eric Dong          TmpValue     = 0;
182642645c3dcf0488c616422dcdfd1596939223f432Eric Dong        } else {
182742645c3dcf0488c616422dcdfd1596939223f432Eric Dong          *TopOfScreen = FindTopOfScreenMenu(*HighlightMenu, BottomRow - TopRow - MenuOption->Skip, &TmpValue);
182842645c3dcf0488c616422dcdfd1596939223f432Eric Dong        }
182942645c3dcf0488c616422dcdfd1596939223f432Eric Dong
183042645c3dcf0488c616422dcdfd1596939223f432Eric Dong        *SkipValue   = TmpValue;
1831336c8e116b3e2e11dccdac163d0a85fc3c58fd3dEric Dong      }
183242645c3dcf0488c616422dcdfd1596939223f432Eric Dong    } else {
183342645c3dcf0488c616422dcdfd1596939223f432Eric Dong      //
183442645c3dcf0488c616422dcdfd1596939223f432Eric Dong      // Last time highlight menu has disappear, find the first highlightable menu as the defalut one.
183542645c3dcf0488c616422dcdfd1596939223f432Eric Dong      //
183642645c3dcf0488c616422dcdfd1596939223f432Eric Dong      *HighlightMenu = gMenuOption.ForwardLink;
183742645c3dcf0488c616422dcdfd1596939223f432Eric Dong      if (!IsListEmpty (&gMenuOption)) {
183842645c3dcf0488c616422dcdfd1596939223f432Eric Dong        MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow, TRUE);
183942645c3dcf0488c616422dcdfd1596939223f432Eric Dong      }
184042645c3dcf0488c616422dcdfd1596939223f432Eric Dong      *TopOfScreen   = gMenuOption.ForwardLink;
184142645c3dcf0488c616422dcdfd1596939223f432Eric Dong      *SkipValue = 0;
184242645c3dcf0488c616422dcdfd1596939223f432Eric Dong    }
184342645c3dcf0488c616422dcdfd1596939223f432Eric Dong
184442645c3dcf0488c616422dcdfd1596939223f432Eric Dong  } else if (FormData->HighLightedStatement != NULL) {
184542645c3dcf0488c616422dcdfd1596939223f432Eric Dong    if (IsSavedHighlightStatement (FormData->HighLightedStatement)) {
184642645c3dcf0488c616422dcdfd1596939223f432Eric Dong      //
184742645c3dcf0488c616422dcdfd1596939223f432Eric Dong      // Input highlight menu is same as last time highlight menu.
184842645c3dcf0488c616422dcdfd1596939223f432Eric Dong      // Base on last time highlight menu to set the top of screen menu and highlight menu.
184942645c3dcf0488c616422dcdfd1596939223f432Eric Dong      //
185042645c3dcf0488c616422dcdfd1596939223f432Eric Dong      *HighlightMenu = FindHighLightMenuOption(NULL);
185142645c3dcf0488c616422dcdfd1596939223f432Eric Dong      ASSERT (*HighlightMenu != NULL);
185242645c3dcf0488c616422dcdfd1596939223f432Eric Dong
185342645c3dcf0488c616422dcdfd1596939223f432Eric Dong      //
185442645c3dcf0488c616422dcdfd1596939223f432Eric Dong      // Update skip info for this highlight menu.
185542645c3dcf0488c616422dcdfd1596939223f432Eric Dong      //
185642645c3dcf0488c616422dcdfd1596939223f432Eric Dong      MenuOption = MENU_OPTION_FROM_LINK (*HighlightMenu);
185742645c3dcf0488c616422dcdfd1596939223f432Eric Dong      UpdateOptionSkipLines (MenuOption);
185842645c3dcf0488c616422dcdfd1596939223f432Eric Dong
185942645c3dcf0488c616422dcdfd1596939223f432Eric Dong      *TopOfScreen = FindTopOfScreenMenuOption();
186042645c3dcf0488c616422dcdfd1596939223f432Eric Dong      if (*TopOfScreen == NULL) {
1861336c8e116b3e2e11dccdac163d0a85fc3c58fd3dEric Dong        //
186242645c3dcf0488c616422dcdfd1596939223f432Eric Dong        // Not found last time top of screen menu, so base on current highlight menu
186342645c3dcf0488c616422dcdfd1596939223f432Eric Dong        // to find the new top of screen menu.
186442645c3dcf0488c616422dcdfd1596939223f432Eric Dong        // Make the current highlight menu at the bottom of the form to calculate the
186542645c3dcf0488c616422dcdfd1596939223f432Eric Dong        // top of screen menu.
1866336c8e116b3e2e11dccdac163d0a85fc3c58fd3dEric Dong        //
186742645c3dcf0488c616422dcdfd1596939223f432Eric Dong        if (MenuOption->Skip >= BottomRow - TopRow) {
186842645c3dcf0488c616422dcdfd1596939223f432Eric Dong          *TopOfScreen = *HighlightMenu;
186942645c3dcf0488c616422dcdfd1596939223f432Eric Dong          TmpValue     = 0;
187042645c3dcf0488c616422dcdfd1596939223f432Eric Dong        } else {
187142645c3dcf0488c616422dcdfd1596939223f432Eric Dong          *TopOfScreen = FindTopOfScreenMenu(*HighlightMenu, BottomRow - TopRow - MenuOption->Skip, &TmpValue);
187242645c3dcf0488c616422dcdfd1596939223f432Eric Dong        }
187342645c3dcf0488c616422dcdfd1596939223f432Eric Dong
187442645c3dcf0488c616422dcdfd1596939223f432Eric Dong        *SkipValue   = TmpValue;
187542645c3dcf0488c616422dcdfd1596939223f432Eric Dong      } else {
187642645c3dcf0488c616422dcdfd1596939223f432Eric Dong        AdjustDateAndTimePosition(TRUE, TopOfScreen);
187742645c3dcf0488c616422dcdfd1596939223f432Eric Dong        MenuOption = MENU_OPTION_FROM_LINK (*TopOfScreen);
187842645c3dcf0488c616422dcdfd1596939223f432Eric Dong        UpdateOptionSkipLines (MenuOption);
187942645c3dcf0488c616422dcdfd1596939223f432Eric Dong
188042645c3dcf0488c616422dcdfd1596939223f432Eric Dong        *SkipValue = gHighligthMenuInfo.SkipValue;
1881336c8e116b3e2e11dccdac163d0a85fc3c58fd3dEric Dong      }
188242645c3dcf0488c616422dcdfd1596939223f432Eric Dong      AdjustDateAndTimePosition(TRUE, TopOfScreen);
188342645c3dcf0488c616422dcdfd1596939223f432Eric Dong    } else {
188442645c3dcf0488c616422dcdfd1596939223f432Eric Dong      //
188542645c3dcf0488c616422dcdfd1596939223f432Eric Dong      // Input highlight menu is not save as last time highlight menu.
188642645c3dcf0488c616422dcdfd1596939223f432Eric Dong      //
188742645c3dcf0488c616422dcdfd1596939223f432Eric Dong      *HighlightMenu = FindHighLightMenuOption(FormData->HighLightedStatement);
188842645c3dcf0488c616422dcdfd1596939223f432Eric Dong      MenuOption = MENU_OPTION_FROM_LINK (*HighlightMenu);
188942645c3dcf0488c616422dcdfd1596939223f432Eric Dong      UpdateOptionSkipLines (MenuOption);
18907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
189142645c3dcf0488c616422dcdfd1596939223f432Eric Dong      //
189242645c3dcf0488c616422dcdfd1596939223f432Eric Dong      // Make the current highlight menu at the bottom of the form to calculate the
189342645c3dcf0488c616422dcdfd1596939223f432Eric Dong      // top of screen menu.
189442645c3dcf0488c616422dcdfd1596939223f432Eric Dong      //
189542645c3dcf0488c616422dcdfd1596939223f432Eric Dong      if (MenuOption->Skip >= BottomRow - TopRow) {
189642645c3dcf0488c616422dcdfd1596939223f432Eric Dong        *TopOfScreen = *HighlightMenu;
189742645c3dcf0488c616422dcdfd1596939223f432Eric Dong        TmpValue     = 0;
189842645c3dcf0488c616422dcdfd1596939223f432Eric Dong      } else {
189942645c3dcf0488c616422dcdfd1596939223f432Eric Dong        *TopOfScreen = FindTopOfScreenMenu(*HighlightMenu, BottomRow - TopRow - MenuOption->Skip, &TmpValue);
190042645c3dcf0488c616422dcdfd1596939223f432Eric Dong      }
190142645c3dcf0488c616422dcdfd1596939223f432Eric Dong
190242645c3dcf0488c616422dcdfd1596939223f432Eric Dong      *SkipValue   = TmpValue;
190342645c3dcf0488c616422dcdfd1596939223f432Eric Dong    }
190442645c3dcf0488c616422dcdfd1596939223f432Eric Dong    AdjustDateAndTimePosition(TRUE, TopOfScreen);
19057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else {
190642645c3dcf0488c616422dcdfd1596939223f432Eric Dong    //
190742645c3dcf0488c616422dcdfd1596939223f432Eric Dong    // If not has input highlight statement, just return the first one in this form.
190842645c3dcf0488c616422dcdfd1596939223f432Eric Dong    //
190942645c3dcf0488c616422dcdfd1596939223f432Eric Dong    *TopOfScreen   = gMenuOption.ForwardLink;
191042645c3dcf0488c616422dcdfd1596939223f432Eric Dong    *HighlightMenu = gMenuOption.ForwardLink;
191142645c3dcf0488c616422dcdfd1596939223f432Eric Dong    if (!IsListEmpty (&gMenuOption)) {
191242645c3dcf0488c616422dcdfd1596939223f432Eric Dong      MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow, TRUE);
191342645c3dcf0488c616422dcdfd1596939223f432Eric Dong    }
191442645c3dcf0488c616422dcdfd1596939223f432Eric Dong    *SkipValue     = 0;
19157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
1916ab2cf8eabb1e737697f910de94473f5eddeaede4Eric Dong
1917b2f35637da091be37748203a5817a1c732c69e12Dandan Bi  gMisMatch = FALSE;
1918b2f35637da091be37748203a5817a1c732c69e12Dandan Bi
1919ab2cf8eabb1e737697f910de94473f5eddeaede4Eric Dong  //
1920ab2cf8eabb1e737697f910de94473f5eddeaede4Eric Dong  // First enter to show the menu, update highlight info.
1921ab2cf8eabb1e737697f910de94473f5eddeaede4Eric Dong  //
1922ab2cf8eabb1e737697f910de94473f5eddeaede4Eric Dong  UpdateHighlightMenuInfo (*HighlightMenu, *TopOfScreen, *SkipValue);
19237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
19247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
19257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
192642645c3dcf0488c616422dcdfd1596939223f432Eric Dong  Record the highlight menu and top of screen menu info.
1927af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
192842645c3dcf0488c616422dcdfd1596939223f432Eric Dong  @param  Highlight               The menu opton which is highlight.
192942645c3dcf0488c616422dcdfd1596939223f432Eric Dong  @param  TopOfScreen             The menu opton which is at the top of the form.
193042645c3dcf0488c616422dcdfd1596939223f432Eric Dong  @param  SkipValue               The skip line info for the top of screen menu.
1931af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
1932af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong**/
1933af047db78d297ca33dd74e5e749166bb17a4cc4eEric DongVOID
1934af047db78d297ca33dd74e5e749166bb17a4cc4eEric DongUpdateHighlightMenuInfo (
193542645c3dcf0488c616422dcdfd1596939223f432Eric Dong  IN  LIST_ENTRY                      *Highlight,
193642645c3dcf0488c616422dcdfd1596939223f432Eric Dong  IN  LIST_ENTRY                      *TopOfScreen,
193742645c3dcf0488c616422dcdfd1596939223f432Eric Dong  IN  UINTN                           SkipValue
1938af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  )
1939af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong{
194042645c3dcf0488c616422dcdfd1596939223f432Eric Dong  UI_MENU_OPTION                  *MenuOption;
1941af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  FORM_DISPLAY_ENGINE_STATEMENT   *Statement;
1942af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
194342645c3dcf0488c616422dcdfd1596939223f432Eric Dong  gHighligthMenuInfo.HiiHandle  = gFormData->HiiHandle;
194442645c3dcf0488c616422dcdfd1596939223f432Eric Dong  gHighligthMenuInfo.FormId     = gFormData->FormId;
194542645c3dcf0488c616422dcdfd1596939223f432Eric Dong  gHighligthMenuInfo.SkipValue  = (UINT16)SkipValue;
1946af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
194742645c3dcf0488c616422dcdfd1596939223f432Eric Dong  if (!IsListEmpty (&gMenuOption)) {
194842645c3dcf0488c616422dcdfd1596939223f432Eric Dong    MenuOption = MENU_OPTION_FROM_LINK (Highlight);
194942645c3dcf0488c616422dcdfd1596939223f432Eric Dong    Statement  = MenuOption->ThisTag;
1950af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
195142645c3dcf0488c616422dcdfd1596939223f432Eric Dong    gUserInput->SelectedStatement = Statement;
1952336c8e116b3e2e11dccdac163d0a85fc3c58fd3dEric Dong
195342645c3dcf0488c616422dcdfd1596939223f432Eric Dong    gHighligthMenuInfo.HLTSequence   = MenuOption->Sequence;
195442645c3dcf0488c616422dcdfd1596939223f432Eric Dong    gHighligthMenuInfo.HLTQuestionId = GetQuestionIdInfo(Statement->OpCode);
195542645c3dcf0488c616422dcdfd1596939223f432Eric Dong    if (gHighligthMenuInfo.HLTQuestionId == 0) {
195642645c3dcf0488c616422dcdfd1596939223f432Eric Dong      //
195742645c3dcf0488c616422dcdfd1596939223f432Eric Dong      // if question id == 0, save the opcode buffer..
195842645c3dcf0488c616422dcdfd1596939223f432Eric Dong      //
195942645c3dcf0488c616422dcdfd1596939223f432Eric Dong      if (gHighligthMenuInfo.HLTOpCode != NULL) {
196042645c3dcf0488c616422dcdfd1596939223f432Eric Dong        FreePool (gHighligthMenuInfo.HLTOpCode);
1961336c8e116b3e2e11dccdac163d0a85fc3c58fd3dEric Dong      }
196242645c3dcf0488c616422dcdfd1596939223f432Eric Dong      gHighligthMenuInfo.HLTOpCode = AllocateCopyPool (Statement->OpCode->Length, Statement->OpCode);
196342645c3dcf0488c616422dcdfd1596939223f432Eric Dong      ASSERT (gHighligthMenuInfo.HLTOpCode != NULL);
196442645c3dcf0488c616422dcdfd1596939223f432Eric Dong
196542645c3dcf0488c616422dcdfd1596939223f432Eric Dong      gHighligthMenuInfo.HLTIndex = GetIndexInfoForOpcode(Statement->OpCode);
196642645c3dcf0488c616422dcdfd1596939223f432Eric Dong    }
196742645c3dcf0488c616422dcdfd1596939223f432Eric Dong
196842645c3dcf0488c616422dcdfd1596939223f432Eric Dong    MenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
196942645c3dcf0488c616422dcdfd1596939223f432Eric Dong    Statement  = MenuOption->ThisTag;
197042645c3dcf0488c616422dcdfd1596939223f432Eric Dong
197142645c3dcf0488c616422dcdfd1596939223f432Eric Dong    gHighligthMenuInfo.TOSQuestionId = GetQuestionIdInfo(Statement->OpCode);
197242645c3dcf0488c616422dcdfd1596939223f432Eric Dong    if (gHighligthMenuInfo.TOSQuestionId == 0) {
197342645c3dcf0488c616422dcdfd1596939223f432Eric Dong      //
197442645c3dcf0488c616422dcdfd1596939223f432Eric Dong      // if question id == 0, save the opcode buffer..
197542645c3dcf0488c616422dcdfd1596939223f432Eric Dong      //
197642645c3dcf0488c616422dcdfd1596939223f432Eric Dong      if (gHighligthMenuInfo.TOSOpCode != NULL) {
197742645c3dcf0488c616422dcdfd1596939223f432Eric Dong        FreePool (gHighligthMenuInfo.TOSOpCode);
197842645c3dcf0488c616422dcdfd1596939223f432Eric Dong      }
197942645c3dcf0488c616422dcdfd1596939223f432Eric Dong      gHighligthMenuInfo.TOSOpCode = AllocateCopyPool (Statement->OpCode->Length, Statement->OpCode);
198042645c3dcf0488c616422dcdfd1596939223f432Eric Dong      ASSERT (gHighligthMenuInfo.TOSOpCode != NULL);
198142645c3dcf0488c616422dcdfd1596939223f432Eric Dong
198242645c3dcf0488c616422dcdfd1596939223f432Eric Dong      gHighligthMenuInfo.TOSIndex = GetIndexInfoForOpcode(Statement->OpCode);
1983336c8e116b3e2e11dccdac163d0a85fc3c58fd3dEric Dong    }
1984af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  } else {
198542645c3dcf0488c616422dcdfd1596939223f432Eric Dong    gUserInput->SelectedStatement    = NULL;
198642645c3dcf0488c616422dcdfd1596939223f432Eric Dong
198742645c3dcf0488c616422dcdfd1596939223f432Eric Dong    gHighligthMenuInfo.HLTSequence   = 0;
198842645c3dcf0488c616422dcdfd1596939223f432Eric Dong    gHighligthMenuInfo.HLTQuestionId = 0;
198942645c3dcf0488c616422dcdfd1596939223f432Eric Dong    if (gHighligthMenuInfo.HLTOpCode != NULL) {
199042645c3dcf0488c616422dcdfd1596939223f432Eric Dong      FreePool (gHighligthMenuInfo.HLTOpCode);
1991336c8e116b3e2e11dccdac163d0a85fc3c58fd3dEric Dong    }
199242645c3dcf0488c616422dcdfd1596939223f432Eric Dong    gHighligthMenuInfo.HLTOpCode     = NULL;
199342645c3dcf0488c616422dcdfd1596939223f432Eric Dong    gHighligthMenuInfo.HLTIndex      = 0;
1994af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
199542645c3dcf0488c616422dcdfd1596939223f432Eric Dong    gHighligthMenuInfo.TOSQuestionId = 0;
199642645c3dcf0488c616422dcdfd1596939223f432Eric Dong    if (gHighligthMenuInfo.TOSOpCode != NULL) {
199742645c3dcf0488c616422dcdfd1596939223f432Eric Dong      FreePool (gHighligthMenuInfo.TOSOpCode);
199842645c3dcf0488c616422dcdfd1596939223f432Eric Dong    }
199942645c3dcf0488c616422dcdfd1596939223f432Eric Dong    gHighligthMenuInfo.TOSOpCode     = NULL;
200042645c3dcf0488c616422dcdfd1596939223f432Eric Dong    gHighligthMenuInfo.TOSIndex      = 0;
200142645c3dcf0488c616422dcdfd1596939223f432Eric Dong  }
2002af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong}
2003af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2004af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong/**
2005af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Update attribut for this menu.
2006af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2007af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  MenuOption               The menu opton which this attribut used to.
2008af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  Highlight                Whether this menu will be highlight.
2009af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2010af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong**/
2011af047db78d297ca33dd74e5e749166bb17a4cc4eEric DongVOID
2012af047db78d297ca33dd74e5e749166bb17a4cc4eEric DongSetDisplayAttribute (
2013af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UI_MENU_OPTION                  *MenuOption,
2014af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN BOOLEAN                         Highlight
2015af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  )
2016af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong{
2017af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  FORM_DISPLAY_ENGINE_STATEMENT   *Statement;
2018af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2019af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Statement = MenuOption->ThisTag;
2020af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2021af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  if (Highlight) {
2022af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ());
2023af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    return;
2024af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  }
2025af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2026af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  if (MenuOption->GrayOut) {
2027af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    gST->ConOut->SetAttribute (gST->ConOut, GetGrayedTextColor ());
2028af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  } else {
2029af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    if (Statement->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) {
2030af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      gST->ConOut->SetAttribute (gST->ConOut, GetSubTitleTextColor ());
2031af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    } else {
2032af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
2033af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    }
2034af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  }
2035af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong}
2036af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2037af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong/**
2038af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Print string for this menu option.
2039af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2040af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  MenuOption               The menu opton which this attribut used to.
2041af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  Col                      The column that this string will be print at.
2042af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  Row                      The row that this string will be print at.
2043af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  String                   The string which need to print.
2044af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  Width                    The width need to print, if string is less than the
2045af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong                                   width, the block space will be used.
2046af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  Highlight                Whether this menu will be highlight.
2047af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2048af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong**/
2049af047db78d297ca33dd74e5e749166bb17a4cc4eEric DongVOID
2050af047db78d297ca33dd74e5e749166bb17a4cc4eEric DongDisplayMenuString (
2051af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UI_MENU_OPTION         *MenuOption,
2052af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UINTN                  Col,
2053af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UINTN                  Row,
2054af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN CHAR16                 *String,
2055af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UINTN                  Width,
2056af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN BOOLEAN                Highlight
2057af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  )
2058af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong{
2059af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINTN            Length;
2060af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2061af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
2062af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  // Print string with normal color.
2063af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
2064af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  if (!Highlight) {
2065af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    PrintStringAtWithWidth (Col, Row, String, Width);
2066af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    return;
2067af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  }
2068af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2069af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
2070af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  // Print the highlight menu string.
2071af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  // First print the highlight string.
2072af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
2073af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  SetDisplayAttribute(MenuOption, TRUE);
2074af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Length = PrintStringAt (Col, Row, String);
2075af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2076af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
2077af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  // Second, clean the empty after the string.
2078af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
2079af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  SetDisplayAttribute(MenuOption, FALSE);
2080af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  PrintStringAtWithWidth (Col + Length, Row, L"", Width - Length);
2081af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong}
2082af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2083af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong/**
208428401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  Check whether this menu can has option string.
208528401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
208628401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  @param  MenuOption               The menu opton which this attribut used to.
208728401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
208828401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  @retval TRUE                     This menu option can have option string.
208928401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  @retval FALSE                    This menu option can't have option string.
209028401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
209128401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong**/
209228401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric DongBOOLEAN
209328401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric DongHasOptionString (
209428401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  IN UI_MENU_OPTION                  *MenuOption
209528401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  )
209628401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong{
209728401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  FORM_DISPLAY_ENGINE_STATEMENT   *Statement;
209828401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  CHAR16                          *String;
209928401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  UINTN                           Size;
210028401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  EFI_IFR_TEXT                    *TestOp;
210128401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
210228401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  Size = 0;
210328401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  Statement = MenuOption->ThisTag;
210428401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
210528401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  //
210628401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  // See if the second text parameter is really NULL
210728401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  //
210828401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  if (Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) {
210928401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    TestOp = (EFI_IFR_TEXT *) Statement->OpCode;
211028401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    if (TestOp->TextTwo != 0) {
211128401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong      String = GetToken (TestOp->TextTwo, gFormData->HiiHandle);
211228401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong      Size   = StrLen (String);
211328401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong      FreePool (String);
211428401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    }
211528401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  }
211628401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
211728401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  if ((Statement->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) ||
211828401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    (Statement->OpCode->OpCode == EFI_IFR_REF_OP) ||
211928401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    (Statement->OpCode->OpCode == EFI_IFR_PASSWORD_OP) ||
212028401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    (Statement->OpCode->OpCode == EFI_IFR_ACTION_OP) ||
212128401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    (Statement->OpCode->OpCode == EFI_IFR_RESET_BUTTON_OP) ||
212228401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    //
212328401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    // Allow a wide display if text op-code and no secondary text op-code
212428401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    //
212528401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    ((Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) && (Size == 0))
212628401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    ) {
212728401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
212828401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    return FALSE;
212928401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  }
213028401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
213128401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  return TRUE;
213228401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong}
213328401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
213423c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong/**
213523c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  Double confirm with user about the action.
213623c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
213723c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  @param  Action               The user input action.
213823c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
213923c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  @retval TRUE                 User confirm with the input or not need user confirm.
214023c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  @retval FALSE                User want ignore this input.
214123c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
214223c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong**/
214323c7d4258f3a916c916f16e1cdf4c217a539b984Eric DongBOOLEAN
214423c7d4258f3a916c916f16e1cdf4c217a539b984Eric DongFxConfirmPopup (
214523c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  IN UINT32   Action
214623c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  )
214723c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong{
214823c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  EFI_INPUT_KEY                   Key;
214923c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  CHAR16                          *CfmStr;
215023c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  UINTN                           CfmStrLen;
215123c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  UINT32                          CheckFlags;
215223c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  BOOLEAN                         RetVal;
215323c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  UINTN                           CatLen;
21545ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi  UINTN                           MaxLen;
215523c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
215623c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  CfmStrLen = 0;
215723c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  CatLen    = StrLen (gConfirmMsgConnect);
215823c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
215923c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  //
216023c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  // Below action need extra popup dialog to confirm.
216123c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  //
216223c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  CheckFlags = BROWSER_ACTION_DISCARD |
216323c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong               BROWSER_ACTION_DEFAULT |
216423c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong               BROWSER_ACTION_SUBMIT |
216523c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong               BROWSER_ACTION_RESET |
216623c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong               BROWSER_ACTION_EXIT;
216723c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
216823c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  //
216923c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  // Not need to confirm with user, just return TRUE.
217023c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  //
217123c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  if ((Action & CheckFlags) == 0) {
217223c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    return TRUE;
217323c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  }
217423c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
217523c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  if ((Action & BROWSER_ACTION_DISCARD) == BROWSER_ACTION_DISCARD) {
217623c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    CfmStrLen += StrLen (gConfirmDiscardMsg);
217723c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  }
217823c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
217923c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  if ((Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {
218023c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    if (CfmStrLen != 0) {
218123c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong      CfmStrLen += CatLen;
218223c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    }
218323c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
218423c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    CfmStrLen += StrLen (gConfirmDefaultMsg);
218523c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  }
218623c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
218723c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  if ((Action & BROWSER_ACTION_SUBMIT)  == BROWSER_ACTION_SUBMIT) {
218823c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    if (CfmStrLen != 0) {
218923c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong      CfmStrLen += CatLen;
219023c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    }
219123c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
219223c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    CfmStrLen += StrLen (gConfirmSubmitMsg);
219323c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  }
219423c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
219523c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  if ((Action & BROWSER_ACTION_RESET)  == BROWSER_ACTION_RESET) {
219623c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    if (CfmStrLen != 0) {
219723c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong      CfmStrLen += CatLen;
219823c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    }
219923c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
220023c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    CfmStrLen += StrLen (gConfirmResetMsg);
220123c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  }
220223c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
220323c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  if ((Action & BROWSER_ACTION_EXIT)  == BROWSER_ACTION_EXIT) {
220423c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    if (CfmStrLen != 0) {
220523c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong      CfmStrLen += CatLen;
220623c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    }
220723c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
220823c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    CfmStrLen += StrLen (gConfirmExitMsg);
220923c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  }
221023c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
221123c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  //
221223c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  // Allocate buffer to save the string.
221323c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  // String + "?" + "\0"
221423c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  //
22155ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi  MaxLen = CfmStrLen + 1 + 1;
22165ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi  CfmStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));
221723c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  ASSERT (CfmStr != NULL);
221823c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
221923c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  if ((Action & BROWSER_ACTION_DISCARD) == BROWSER_ACTION_DISCARD) {
22205ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi    StrCpyS (CfmStr, MaxLen, gConfirmDiscardMsg);
222123c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  }
222223c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
222323c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  if ((Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {
222423c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    if (CfmStr[0] != 0) {
22255ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi      StrCatS (CfmStr, MaxLen, gConfirmMsgConnect);
22265ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi      StrCatS (CfmStr, MaxLen, gConfirmDefaultMsg2nd);
222723c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    } else {
22285ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi      StrCpyS (CfmStr, MaxLen, gConfirmDefaultMsg);
222923c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    }
223023c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  }
223123c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
223223c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  if ((Action & BROWSER_ACTION_SUBMIT)  == BROWSER_ACTION_SUBMIT) {
223323c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    if (CfmStr[0] != 0) {
22345ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi      StrCatS (CfmStr, MaxLen, gConfirmMsgConnect);
22355ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi      StrCatS (CfmStr, MaxLen, gConfirmSubmitMsg2nd);
223623c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    } else {
22375ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi      StrCpyS (CfmStr, MaxLen, gConfirmSubmitMsg);
223823c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    }
223923c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  }
224023c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
224123c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  if ((Action & BROWSER_ACTION_RESET)  == BROWSER_ACTION_RESET) {
224223c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    if (CfmStr[0] != 0) {
22435ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi      StrCatS (CfmStr, MaxLen, gConfirmMsgConnect);
22445ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi      StrCatS (CfmStr, MaxLen, gConfirmResetMsg2nd);
224523c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    } else {
22465ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi      StrCpyS (CfmStr, MaxLen, gConfirmResetMsg);
224723c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    }
224823c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  }
224923c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
225023c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  if ((Action & BROWSER_ACTION_EXIT)  == BROWSER_ACTION_EXIT) {
225123c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    if (CfmStr[0] != 0) {
22525ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi      StrCatS (CfmStr, MaxLen, gConfirmMsgConnect);
22535ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi      StrCatS (CfmStr, MaxLen, gConfirmExitMsg2nd);
225423c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    } else {
22555ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi      StrCpyS (CfmStr, MaxLen, gConfirmExitMsg);
225623c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    }
225723c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  }
225823c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
22595ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi  StrCatS (CfmStr, MaxLen, gConfirmMsgEnd);
226023c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
226123c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  do {
226223c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    CreateDialog (&Key, gEmptyString, CfmStr, gConfirmOpt, gEmptyString, NULL);
226323c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  } while (((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (gConfirmOptYes[0] | UPPER_LOWER_CASE_OFFSET)) &&
2264299c3aec0fb4f3bd9a4f5e1eae9be83f7702b9a5Dandan Bi           ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (gConfirmOptNo[0] | UPPER_LOWER_CASE_OFFSET)) &&
2265299c3aec0fb4f3bd9a4f5e1eae9be83f7702b9a5Dandan Bi           (Key.ScanCode != SCAN_ESC));
226623c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
226723c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (gConfirmOptYes[0] | UPPER_LOWER_CASE_OFFSET)) {
226823c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    RetVal = TRUE;
226923c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  } else {
227023c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong    RetVal = FALSE;
227123c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  }
227223c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
227323c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  FreePool (CfmStr);
227423c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
227523c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong  return RetVal;
227623c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong}
227728401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
227828401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong/**
2279af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Print string for this menu option.
2280af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2281af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  MenuOption               The menu opton which this attribut used to.
2282af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  SkipWidth                The skip width between the left to the start of the prompt.
2283af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  BeginCol                 The begin column for one menu.
2284af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  SkipLine                 The skip line for this menu.
2285af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  BottomRow                The bottom row for this form.
2286af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @param  Highlight                Whether this menu will be highlight.
2287f0c5095b274b2b35867d5245119aa1aba0acc87eEric Dong  @param  UpdateCol                Whether need to update the column info for Date/Time.
2288af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2289af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  @retval EFI_SUCESSS              Process the user selection success.
2290af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2291af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong**/
2292af047db78d297ca33dd74e5e749166bb17a4cc4eEric DongEFI_STATUS
2293af047db78d297ca33dd74e5e749166bb17a4cc4eEric DongDisplayOneMenu (
2294af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UI_MENU_OPTION                  *MenuOption,
2295af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UINTN                           SkipWidth,
2296af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UINTN                           BeginCol,
2297af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UINTN                           SkipLine,
2298af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  IN UINTN                           BottomRow,
2299f0c5095b274b2b35867d5245119aa1aba0acc87eEric Dong  IN BOOLEAN                         Highlight,
2300f0c5095b274b2b35867d5245119aa1aba0acc87eEric Dong  IN BOOLEAN                         UpdateCol
2301af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  )
2302af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong{
2303af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  FORM_DISPLAY_ENGINE_STATEMENT   *Statement;
2304af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINTN                           Index;
2305af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINT16                          Width;
2306af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINT16                          PromptWidth;
2307af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  CHAR16                          *StringPtr;
2308af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  CHAR16                          *OptionString;
2309af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  CHAR16                          *OutputString;
2310af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINT16                          GlyphWidth;
2311af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINTN                           Temp;
2312af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINTN                           Temp2;
2313af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINTN                           Temp3;
2314af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  EFI_STATUS                      Status;
2315af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINTN                           Row;
23168c9c60b66224364217f80ca56a0742c26832cc45Dandan Bi  BOOLEAN                         IsProcessingFirstRow;
2317af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINTN                           Col;
2318af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  UINTN                           PromptLineNum;
231928401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  UINTN                           OptionLineNum;
2320af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  CHAR16                          AdjustValue;
232128401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  UINTN                           MaxRow;
2322af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2323af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Statement = MenuOption->ThisTag;
2324af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Temp      = SkipLine;
2325af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Temp2     = SkipLine;
2326af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Temp3     = SkipLine;
232728401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  AdjustValue   = 0;
232828401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  PromptLineNum = 0;
232928401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  OptionLineNum = 0;
233028401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  MaxRow        = 0;
23318c9c60b66224364217f80ca56a0742c26832cc45Dandan Bi  IsProcessingFirstRow = TRUE;
2332af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2333af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
2334af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  // Set default color.
2335af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
2336af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  SetDisplayAttribute (MenuOption, FALSE);
2337af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2338af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
2339af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  // 1. Paint the option string.
2340af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
2341af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  Status = ProcessOptions (MenuOption, FALSE, &OptionString, FALSE);
2342af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  if (EFI_ERROR (Status)) {
2343af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    return Status;
2344af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  }
2345af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2346af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  if (OptionString != NULL) {
2347af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
2348af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      //
2349af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      // Adjust option string for date/time opcode.
2350af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      //
2351f0c5095b274b2b35867d5245119aa1aba0acc87eEric Dong      ProcessStringForDateTime(MenuOption, OptionString, UpdateCol);
2352af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    }
2353af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2354af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    Width       = (UINT16) gOptionBlockWidth - 1;
235528401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    Row         = MenuOption->Row;
2356af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    GlyphWidth  = 1;
235728401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    OptionLineNum = 0;
2358af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2359af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
2360af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if (((Temp2 == 0)) && (Row <= BottomRow)) {
2361af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
2362af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          //
2363af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          // For date/time question, it has three menu options for this qustion.
2364af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          // The first/second menu options with the skip value is 0. the last one
2365af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          // with skip value is 1.
2366af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          //
2367af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          if (MenuOption->Skip != 0) {
2368af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            //
2369af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            // For date/ time, print the last past (year for date and second for time)
2370af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            // - 7 means skip [##/##/ for date and [##:##: for time.
2371af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            //
2372af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            DisplayMenuString (MenuOption,MenuOption->OptCol, Row, OutputString, Width + 1 - 7, Highlight);
2373af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          } else {
2374af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            //
2375af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            // For date/ time, print the first and second past (year for date and second for time)
2376f0c5095b274b2b35867d5245119aa1aba0acc87eEric Dong            // The OutputString has a NARROW_CHAR or WIDE_CHAR at the begin of the string,
2377f0c5095b274b2b35867d5245119aa1aba0acc87eEric Dong            // so need to - 1 to remove it, otherwise, it will clean 1 extr char follow it.
2378f0c5095b274b2b35867d5245119aa1aba0acc87eEric Dong            DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, StrLen (OutputString) - 1, Highlight);
2379af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          }
2380af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        } else {
2381af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, Width + 1, Highlight);
2382af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        }
238328401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong        OptionLineNum++;
2384af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      }
2385af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2386af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      //
2387af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      // If there is more string to process print on the next row and increment the Skip value
2388af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      //
2389af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if (StrLen (&OptionString[Index]) != 0) {
2390af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        if (Temp2 == 0) {
2391af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          Row++;
2392af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          //
2393af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          // Since the Number of lines for this menu entry may or may not be reflected accurately
2394af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          // since the prompt might be 1 lines and option might be many, and vice versa, we need to do
2395af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          // some testing to ensure we are keeping this in-sync.
2396af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          //
2397af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          // If the difference in rows is greater than or equal to the skip value, increase the skip value
2398af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          //
239928401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong          if ((Row - MenuOption->Row) >= MenuOption->Skip) {
2400af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            MenuOption->Skip++;
2401af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          }
2402af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        }
2403af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      }
2404af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2405af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      FreePool (OutputString);
2406af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if (Temp2 != 0) {
2407af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        Temp2--;
2408af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      }
2409af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    }
2410af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2411af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    Highlight = FALSE;
2412af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2413af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    FreePool (OptionString);
2414af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  }
2415af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2416af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
241728401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  // 2. Paint the description.
2418af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
24196f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong  PromptWidth   = GetWidth (MenuOption, &AdjustValue);
242028401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  Row           = MenuOption->Row;
2421af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  GlyphWidth    = 1;
2422af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  PromptLineNum = 0;
2423af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2424af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  if (MenuOption->Description == NULL || MenuOption->Description[0] == '\0') {
242528401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    PrintStringAtWithWidth (BeginCol, Row, L"", PromptWidth + AdjustValue + SkipWidth);
242628401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    PromptLineNum++;
2427af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  } else {
2428af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    for (Index = 0; GetLineByWidth (MenuOption->Description, PromptWidth, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
2429af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if ((Temp == 0) && (Row <= BottomRow)) {
2430af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        //
2431af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        // 1.Clean the start LEFT_SKIPPED_COLUMNS
2432af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        //
2433af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        PrintStringAtWithWidth (BeginCol, Row, L"", SkipWidth);
2434af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
24358c9c60b66224364217f80ca56a0742c26832cc45Dandan Bi        if (Statement->OpCode->OpCode == EFI_IFR_REF_OP && MenuOption->Col >= 2 && IsProcessingFirstRow) {
2436af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          //
2437af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          // Print Arrow for Goto button.
2438af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          //
2439af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          PrintCharAt (
2440af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            MenuOption->Col - 2,
2441af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            Row,
2442af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            GEOMETRICSHAPE_RIGHT_TRIANGLE
2443af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            );
24448c9c60b66224364217f80ca56a0742c26832cc45Dandan Bi          IsProcessingFirstRow = FALSE;
2445af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        }
2446af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        DisplayMenuString (MenuOption, MenuOption->Col, Row, OutputString, PromptWidth + AdjustValue, Highlight);
2447af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        PromptLineNum ++;
2448af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      }
2449af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      //
2450af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      // If there is more string to process print on the next row and increment the Skip value
2451af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      //
2452af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if (StrLen (&MenuOption->Description[Index]) != 0) {
2453af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        if (Temp == 0) {
2454af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          Row++;
2455af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        }
2456af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      }
2457af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2458af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      FreePool (OutputString);
2459af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if (Temp != 0) {
2460af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        Temp--;
2461af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      }
2462af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    }
2463af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2464af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    Highlight = FALSE;
2465af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  }
2466af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2467af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2468af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
246928401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  // 3. If this is a text op with secondary text information
2470af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  //
2471af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  if ((Statement->OpCode->OpCode  == EFI_IFR_TEXT_OP) && (((EFI_IFR_TEXT*)Statement->OpCode)->TextTwo != 0)) {
2472af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    StringPtr   = GetToken (((EFI_IFR_TEXT*)Statement->OpCode)->TextTwo, gFormData->HiiHandle);
2473af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2474af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    Width       = (UINT16) gOptionBlockWidth - 1;
247528401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    Row         = MenuOption->Row;
2476af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    GlyphWidth  = 1;
247728401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    OptionLineNum = 0;
2478af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2479af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    for (Index = 0; GetLineByWidth (StringPtr, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
2480af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if ((Temp3 == 0) && (Row <= BottomRow)) {
2481af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, Width + 1, Highlight);
248228401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong        OptionLineNum++;
2483af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      }
2484af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      //
2485af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      // If there is more string to process print on the next row and increment the Skip value
2486af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      //
2487af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if (StrLen (&StringPtr[Index]) != 0) {
2488af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        if (Temp3 == 0) {
2489af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          Row++;
2490a6a2a95632172022229f0c3d20f0b9adb15dc2faEric Dong          //
2491a6a2a95632172022229f0c3d20f0b9adb15dc2faEric Dong          // If the rows for text two is greater than or equal to the skip value, increase the skip value
2492a6a2a95632172022229f0c3d20f0b9adb15dc2faEric Dong          //
2493a6a2a95632172022229f0c3d20f0b9adb15dc2faEric Dong          if ((Row - MenuOption->Row) >= MenuOption->Skip) {
2494a6a2a95632172022229f0c3d20f0b9adb15dc2faEric Dong            MenuOption->Skip++;
2495a6a2a95632172022229f0c3d20f0b9adb15dc2faEric Dong          }
2496af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        }
2497af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      }
2498af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2499af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      FreePool (OutputString);
2500af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if (Temp3 != 0) {
2501af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        Temp3--;
2502af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      }
2503af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    }
250428401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
2505af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    FreePool (StringPtr);
2506af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  }
2507af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
250828401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  //
250928401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  // 4.Line number for Option string and prompt string are not equal.
251028401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  //  Clean the column whose line number is less.
251128401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  //
251228401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  if (HasOptionString(MenuOption) && (OptionLineNum != PromptLineNum)) {
251328401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    Col    =  OptionLineNum < PromptLineNum ? MenuOption->OptCol : BeginCol;
251428401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    Row    = (OptionLineNum < PromptLineNum ? OptionLineNum : PromptLineNum) + MenuOption->Row;
251528401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    Width  = (UINT16) (OptionLineNum < PromptLineNum ? gOptionBlockWidth : PromptWidth + AdjustValue + SkipWidth);
251628401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    MaxRow = (OptionLineNum < PromptLineNum ? PromptLineNum : OptionLineNum) + MenuOption->Row - 1;
251728401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
251828401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    while (Row <= MaxRow) {
251928401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong      DisplayMenuString (MenuOption, Col, Row++, L"", Width, FALSE);
252028401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong    }
252128401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong  }
252228401a651c65cc3004fbd5a6e9f56fd89c41dbb4Eric Dong
2523af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  return EFI_SUCCESS;
2524af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong}
2525af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2526af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong/**
25277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Display menu and wait for user to select one menu option, then return it.
25287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  If AutoBoot is enabled, then if user doesn't select any option,
25297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  after period of time, it will automatically return the first menu option.
25307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
25317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  FormData               The current form data info.
25327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
25337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval EFI_SUCESSS            Process the user selection success.
25347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval EFI_NOT_FOUND          Process option string for orderedlist/Oneof fail.
25357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
25367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
25377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFI_STATUS
25387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUiDisplayMenu (
25397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  FORM_DISPLAY_ENGINE_FORM  *FormData
25407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
25417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
2542ab369468265cd29a90b385a6e950eda3da16636dEric Dong  UINTN                           SkipValue;
25437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  INTN                            Difference;
25447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           DistanceValue;
25457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           Row;
25467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           Col;
25477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           Temp;
25487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           Temp2;
25497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           TopRow;
25507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           BottomRow;
25517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           Index;
25527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16                          *StringPtr;
2553cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi  CHAR16                          *StringRightPtr;
2554cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi  CHAR16                          *StringErrorPtr;
25557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16                          *OptionString;
25567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16                          *HelpString;
25577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16                          *HelpHeaderString;
25587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16                          *HelpBottomString;
25597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BOOLEAN                         NewLine;
25607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BOOLEAN                         Repaint;
25617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BOOLEAN                         UpArrow;
25627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BOOLEAN                         DownArrow;
25637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_STATUS                      Status;
25647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_INPUT_KEY                   Key;
25657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY                      *Link;
25667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY                      *NewPos;
25677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY                      *TopOfScreen;
25687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY                      *SavedListEntry;
25697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_MENU_OPTION                  *MenuOption;
25707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_MENU_OPTION                  *NextMenuOption;
25717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_MENU_OPTION                  *SavedMenuOption;
25727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_CONTROL_FLAG                 ControlFlag;
25737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_SCREEN_OPERATION             ScreenOperation;
25747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FORM_DISPLAY_ENGINE_STATEMENT   *Statement;
25757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BROWSER_HOT_KEY                 *HotKey;
25767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           HelpPageIndex;
25777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           HelpPageCount;
25787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           RowCount;
25797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           HelpLine;
25807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           HelpHeaderLine;
25817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           HelpBottomLine;
25827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BOOLEAN                         MultiHelpPage;
25837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16                          EachLineWidth;
25847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16                          HeaderLineWidth;
25857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16                          BottomLineWidth;
25867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_STRING_ID                   HelpInfo;
25877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UI_EVENT_TYPE                   EventType;
2588af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  BOOLEAN                         SkipHighLight;
2589cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi  EFI_HII_VALUE                   *StatementValue;
25907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
25917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EventType           = UIEventNone;
25927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Status              = EFI_SUCCESS;
25937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HelpString          = NULL;
25947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HelpHeaderString    = NULL;
25957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HelpBottomString    = NULL;
25967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OptionString        = NULL;
25977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ScreenOperation     = UiNoOperation;
25987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  NewLine             = TRUE;
25997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HelpPageCount       = 0;
26007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HelpLine            = 0;
26017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  RowCount            = 0;
26027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HelpBottomLine      = 0;
26037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HelpHeaderLine      = 0;
26047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HelpPageIndex       = 0;
26057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  MultiHelpPage       = FALSE;
26067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EachLineWidth       = 0;
26077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HeaderLineWidth     = 0;
26087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BottomLineWidth     = 0;
26097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UpArrow             = FALSE;
26107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  DownArrow           = FALSE;
26117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  SkipValue           = 0;
2612af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  SkipHighLight       = FALSE;
26137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  NextMenuOption      = NULL;
26157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  SavedMenuOption     = NULL;
26167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HotKey              = NULL;
26177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Repaint             = TRUE;
26187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  MenuOption          = NULL;
2619af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong  gModalSkipColumn    = (CHAR16) (gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 6;
26207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ZeroMem (&Key, sizeof (EFI_INPUT_KEY));
26227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  TopRow    = gStatementDimensions.TopRow    + SCROLL_ARROW_HEIGHT;
26247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT - 1;
26257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Row = TopRow;
26277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
2628af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong    Col = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS + gModalSkipColumn;
26297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else {
26307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Col = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS;
26317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
26327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FindTopMenu(FormData, &TopOfScreen, &NewPos, &SkipValue);
263442645c3dcf0488c616422dcdfd1596939223f432Eric Dong  if (!IsListEmpty (&gMenuOption)) {
263542645c3dcf0488c616422dcdfd1596939223f432Eric Dong    NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
263642645c3dcf0488c616422dcdfd1596939223f432Eric Dong    gUserInput->SelectedStatement = NextMenuOption->ThisTag;
263742645c3dcf0488c616422dcdfd1596939223f432Eric Dong  }
26387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gST->ConOut->EnableCursor (gST->ConOut, FALSE);
26407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ControlFlag = CfInitialization;
26427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  while (TRUE) {
26437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    switch (ControlFlag) {
26447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfInitialization:
2645af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if ((gOldFormEntry.HiiHandle != FormData->HiiHandle) ||
2646af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          (!CompareGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid))) {
2647af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        //
2648af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        // Clear Statement range if different formset is painted.
2649af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        //
2650af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        ClearLines (
2651af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          gStatementDimensions.LeftColumn,
2652af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          gStatementDimensions.RightColumn,
2653af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          TopRow - SCROLL_ARROW_HEIGHT,
2654af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          BottomRow + SCROLL_ARROW_HEIGHT,
2655af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          GetFieldTextColor ()
2656af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          );
26577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
2659af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      ControlFlag = CfRepaint;
26607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
26617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfRepaint:
26637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfRefreshHighLight;
26647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (Repaint) {
26667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
26677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Display menu
26687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
26697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        DownArrow       = FALSE;
26707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        UpArrow         = FALSE;
26717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Row             = TopRow;
26727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2673af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
2674af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
26757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
2676af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        // 1. Check whether need to print the arrow up.
26777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
2678af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        if (!ValueIsScroll (TRUE, TopOfScreen)) {
2679af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          UpArrow = TRUE;
2680af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        }
2681af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
2682ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong        if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
2683ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong          PrintStringAtWithWidth(gStatementDimensions.LeftColumn + gModalSkipColumn, TopRow - 1, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * gModalSkipColumn);
2684ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong        } else {
2685ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong          PrintStringAtWithWidth(gStatementDimensions.LeftColumn, TopRow - 1, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn);
2686ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong        }
2687af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        if (UpArrow) {
2688af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          gST->ConOut->SetAttribute (gST->ConOut, GetArrowColor ());
2689af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          PrintCharAt (
2690af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            gStatementDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,
26917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            TopRow - SCROLL_ARROW_HEIGHT,
2692af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            ARROW_UP
26937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            );
2694af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
26957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
26967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
26977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
26987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // 2.Paint the menu.
26997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
27007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        for (Link = TopOfScreen; Link != &gMenuOption; Link = Link->ForwardLink) {
27017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          MenuOption          = MENU_OPTION_FROM_LINK (Link);
27027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          MenuOption->Row     = Row;
27037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          MenuOption->Col     = Col;
27047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
2705af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            MenuOption->OptCol  = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS + gPromptBlockWidth + gModalSkipColumn;
27067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          } else {
2707af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            MenuOption->OptCol  = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS + gPromptBlockWidth;
27087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
27097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
27107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (MenuOption->NestInStatement) {
27117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            MenuOption->Col += SUBTITLE_INDENT;
27127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
27137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
27147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
2715af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          // Save the highlight menu, will be used in CfRefreshHighLight case.
27167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
2717af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          if (Link == NewPos) {
2718af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            SavedMenuOption = MenuOption;
2719af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            SkipHighLight   = TRUE;
27207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
2721ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong
2722ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong          if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
272372f2eca287ec08dcc32adbf1bb6756b5b97b6f34Eric Dong            Status = DisplayOneMenu (MenuOption,
27246f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong                            MenuOption->Col - gStatementDimensions.LeftColumn,
2725ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong                            gStatementDimensions.LeftColumn + gModalSkipColumn,
2726ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong                            Link == TopOfScreen ? SkipValue : 0,
2727ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong                            BottomRow,
2728f0c5095b274b2b35867d5245119aa1aba0acc87eEric Dong                            (BOOLEAN) ((Link == NewPos) && IsSelectable(MenuOption)),
2729f0c5095b274b2b35867d5245119aa1aba0acc87eEric Dong                            TRUE
2730ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong                            );
2731ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong          } else {
273272f2eca287ec08dcc32adbf1bb6756b5b97b6f34Eric Dong            Status = DisplayOneMenu (MenuOption,
27336f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong                            MenuOption->Col - gStatementDimensions.LeftColumn,
2734ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong                            gStatementDimensions.LeftColumn,
2735ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong                            Link == TopOfScreen ? SkipValue : 0,
2736ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong                            BottomRow,
2737f0c5095b274b2b35867d5245119aa1aba0acc87eEric Dong                            (BOOLEAN) ((Link == NewPos) && IsSelectable(MenuOption)),
2738f0c5095b274b2b35867d5245119aa1aba0acc87eEric Dong                            TRUE
2739f0c5095b274b2b35867d5245119aa1aba0acc87eEric Dong                            );
2740ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong          }
27417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
274272f2eca287ec08dcc32adbf1bb6756b5b97b6f34Eric Dong          if (EFI_ERROR (Status)) {
274342645c3dcf0488c616422dcdfd1596939223f432Eric Dong            if (gMisMatch) {
274442645c3dcf0488c616422dcdfd1596939223f432Eric Dong              return EFI_SUCCESS;
274542645c3dcf0488c616422dcdfd1596939223f432Eric Dong            } else {
274642645c3dcf0488c616422dcdfd1596939223f432Eric Dong              return Status;
274742645c3dcf0488c616422dcdfd1596939223f432Eric Dong            }
274872f2eca287ec08dcc32adbf1bb6756b5b97b6f34Eric Dong          }
27497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
27507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // 3. Update the row info which will be used by next menu.
27517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
27527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (Link == TopOfScreen) {
27537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Row += MenuOption->Skip - SkipValue;
27547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          } else {
27557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Row += MenuOption->Skip;
27567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
27577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
27587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (Row > BottomRow) {
27597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            if (!ValueIsScroll (FALSE, Link)) {
27607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              DownArrow = TRUE;
27617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            }
27627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
27637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Row = BottomRow + 1;
27647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            break;
27657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
27667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
27677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2768af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        //
2769af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        // 3. Menus in this form may not cover all form, clean the remain field.
2770af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        //
2771af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        while (Row <= BottomRow) {
2772af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
2773ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong            PrintStringAtWithWidth(gStatementDimensions.LeftColumn + gModalSkipColumn, Row++, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * gModalSkipColumn);
2774af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          } else {
2775af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong            PrintStringAtWithWidth(gStatementDimensions.LeftColumn, Row++, L"", gStatementDimensions.RightColumn - gHelpBlockWidth - gStatementDimensions.LeftColumn);
2776af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong          }
27777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
27787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2779af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        //
2780af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        // 4. Print the down arrow row.
2781af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        //
2782ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong        if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
2783ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong          PrintStringAtWithWidth(gStatementDimensions.LeftColumn + gModalSkipColumn, BottomRow + 1, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 *  + gModalSkipColumn);
2784ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong        } else {
2785ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong          PrintStringAtWithWidth(gStatementDimensions.LeftColumn, BottomRow + 1, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn);
2786ae4f5746efc0dde9bb64b537f3a41e66c8729f4dEric Dong        }
27877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (DownArrow) {
27887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          gST->ConOut->SetAttribute (gST->ConOut, GetArrowColor ());
27897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          PrintCharAt (
27907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gStatementDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,
27917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            BottomRow + SCROLL_ARROW_HEIGHT,
27927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            ARROW_DOWN
27937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            );
27947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
27957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
27967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
27977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        MenuOption = NULL;
27987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
27997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
28007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
28017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfRefreshHighLight:
28027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
28037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
28047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // MenuOption: Last menu option that need to remove hilight
28057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //             MenuOption is set to NULL in Repaint
28067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // NewPos:     Current menu option that need to hilight
28077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
28087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfUpdateHelpString;
28097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
281042645c3dcf0488c616422dcdfd1596939223f432Eric Dong      UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);
281142645c3dcf0488c616422dcdfd1596939223f432Eric Dong
2812af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      if (SkipHighLight) {
2813af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        SkipHighLight = FALSE;
281442645c3dcf0488c616422dcdfd1596939223f432Eric Dong        MenuOption    = SavedMenuOption;
281542645c3dcf0488c616422dcdfd1596939223f432Eric Dong        RefreshKeyHelp(gFormData, SavedMenuOption->ThisTag, FALSE);
2816af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong        break;
2817af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong      }
2818af047db78d297ca33dd74e5e749166bb17a4cc4eEric Dong
28198924aecd470f84968369982a69aa30acc7c387dfEric Dong      if (IsListEmpty (&gMenuOption)) {
28208924aecd470f84968369982a69aa30acc7c387dfEric Dong        //
28218924aecd470f84968369982a69aa30acc7c387dfEric Dong        // No menu option, just update the hotkey filed.
28228924aecd470f84968369982a69aa30acc7c387dfEric Dong        //
28238924aecd470f84968369982a69aa30acc7c387dfEric Dong        RefreshKeyHelp(gFormData, NULL, FALSE);
28248924aecd470f84968369982a69aa30acc7c387dfEric Dong        break;
28258924aecd470f84968369982a69aa30acc7c387dfEric Dong      }
28268924aecd470f84968369982a69aa30acc7c387dfEric Dong
28277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (MenuOption != NULL && TopOfScreen == &MenuOption->Link) {
28287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Temp = SkipValue;
28297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      } else {
28307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Temp = 0;
28317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
28327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (NewPos == TopOfScreen) {
28337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Temp2 = SkipValue;
28347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      } else {
28357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Temp2 = 0;
28367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
28377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
28387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (NewPos != NULL && (MenuOption == NULL || NewPos != &MenuOption->Link)) {
28397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (MenuOption != NULL) {
28407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
2841ab369468265cd29a90b385a6e950eda3da16636dEric Dong          // Remove the old highlight menu.
28427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
2843ab369468265cd29a90b385a6e950eda3da16636dEric Dong          Status = DisplayOneMenu (MenuOption,
2844ab369468265cd29a90b385a6e950eda3da16636dEric Dong                          MenuOption->Col - gStatementDimensions.LeftColumn,
2845ab369468265cd29a90b385a6e950eda3da16636dEric Dong                          gStatementDimensions.LeftColumn,
2846ab369468265cd29a90b385a6e950eda3da16636dEric Dong                          Temp,
2847ab369468265cd29a90b385a6e950eda3da16636dEric Dong                          BottomRow,
2848f0c5095b274b2b35867d5245119aa1aba0acc87eEric Dong                          FALSE,
2849ab369468265cd29a90b385a6e950eda3da16636dEric Dong                          FALSE
2850ab369468265cd29a90b385a6e950eda3da16636dEric Dong                          );
28517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
28527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
28537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
28547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // This is the current selected statement
28557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
28567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        MenuOption = MENU_OPTION_FROM_LINK (NewPos);
285742645c3dcf0488c616422dcdfd1596939223f432Eric Dong        RefreshKeyHelp(gFormData, MenuOption->ThisTag, FALSE);
28587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
28597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (!IsSelectable (MenuOption)) {
28607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
28617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
28627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2863ab369468265cd29a90b385a6e950eda3da16636dEric Dong        Status = DisplayOneMenu (MenuOption,
2864ab369468265cd29a90b385a6e950eda3da16636dEric Dong                        MenuOption->Col - gStatementDimensions.LeftColumn,
2865ab369468265cd29a90b385a6e950eda3da16636dEric Dong                        gStatementDimensions.LeftColumn,
2866ab369468265cd29a90b385a6e950eda3da16636dEric Dong                        Temp2,
2867ab369468265cd29a90b385a6e950eda3da16636dEric Dong                        BottomRow,
2868f0c5095b274b2b35867d5245119aa1aba0acc87eEric Dong                        TRUE,
2869f0c5095b274b2b35867d5245119aa1aba0acc87eEric Dong                        FALSE
2870ab369468265cd29a90b385a6e950eda3da16636dEric Dong                        );
28717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
28727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
28737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
28747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUpdateHelpString:
28757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfPrepareToReadKey;
28767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
28777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
28787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
28797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2880ab369468265cd29a90b385a6e950eda3da16636dEric Dong      //
2881ab369468265cd29a90b385a6e950eda3da16636dEric Dong      // NewLine means only update highlight menu (remove old highlight and highlith
2882ab369468265cd29a90b385a6e950eda3da16636dEric Dong      // the new one), not need to full repain the form.
2883ab369468265cd29a90b385a6e950eda3da16636dEric Dong      //
28847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (Repaint || NewLine) {
28858924aecd470f84968369982a69aa30acc7c387dfEric Dong        if (IsListEmpty (&gMenuOption)) {
28868924aecd470f84968369982a69aa30acc7c387dfEric Dong          //
28878924aecd470f84968369982a69aa30acc7c387dfEric Dong          // Don't print anything if no mwnu option.
28888924aecd470f84968369982a69aa30acc7c387dfEric Dong          //
28897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          StringPtr = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
28907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else {
28918924aecd470f84968369982a69aa30acc7c387dfEric Dong          //
28928924aecd470f84968369982a69aa30acc7c387dfEric Dong          // Don't print anything if it is a NULL help token
28938924aecd470f84968369982a69aa30acc7c387dfEric Dong          //
28948924aecd470f84968369982a69aa30acc7c387dfEric Dong          ASSERT(MenuOption != NULL);
28958924aecd470f84968369982a69aa30acc7c387dfEric Dong          HelpInfo = ((EFI_IFR_STATEMENT_HEADER *) ((CHAR8 *)MenuOption->ThisTag->OpCode + sizeof (EFI_IFR_OP_HEADER)))->Help;
2896cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi          Statement = MenuOption->ThisTag;
2897cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi          StatementValue = &Statement->CurrentValue;
28988924aecd470f84968369982a69aa30acc7c387dfEric Dong          if (HelpInfo == 0 || !IsSelectable (MenuOption)) {
2899cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi            if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP && StatementValue->Value.date.Month== 0xff)||(Statement->OpCode->OpCode == EFI_IFR_TIME_OP && StatementValue->Value.time.Hour == 0xff)){
2900cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi              StringPtr = GetToken (STRING_TOKEN (GET_TIME_FAIL), gHiiHandle);
2901cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi            } else {
2902cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi              StringPtr = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
2903cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi            }
29048924aecd470f84968369982a69aa30acc7c387dfEric Dong          } else {
2905cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi            if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP && StatementValue->Value.date.Month== 0xff)||(Statement->OpCode->OpCode == EFI_IFR_TIME_OP && StatementValue->Value.time.Hour == 0xff)){
2906cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi              StringRightPtr = GetToken (HelpInfo, gFormData->HiiHandle);
2907cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi              StringErrorPtr = GetToken (STRING_TOKEN (GET_TIME_FAIL), gHiiHandle);
2908cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi              StringPtr = AllocateZeroPool ((StrLen (StringRightPtr) + StrLen (StringErrorPtr)+ 1 ) * sizeof (CHAR16));
2909cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi              StrCpyS (StringPtr, StrLen (StringRightPtr) + StrLen (StringErrorPtr) + 1, StringRightPtr);
2910cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi              StrCatS (StringPtr, StrLen (StringRightPtr) + StrLen (StringErrorPtr) + 1, StringErrorPtr);
2911cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi              FreePool (StringRightPtr);
2912cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi              FreePool (StringErrorPtr);
2913cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi            } else {
2914cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi              StringPtr = GetToken (HelpInfo, gFormData->HiiHandle);
2915cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi            }
29168924aecd470f84968369982a69aa30acc7c387dfEric Dong          }
29177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
29187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
29197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        RowCount      = BottomRow - TopRow + 1;
29207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        HelpPageIndex = 0;
29217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
29227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // 1.Calculate how many line the help string need to print.
29237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
29247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (HelpString != NULL) {
29257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          FreePool (HelpString);
29267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          HelpString = NULL;
29277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
29287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        HelpLine = ProcessHelpString (StringPtr, &HelpString, &EachLineWidth, RowCount);
29297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        FreePool (StringPtr);
29307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
29317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (HelpLine > RowCount) {
29327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          MultiHelpPage   = TRUE;
29337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          StringPtr       = GetToken (STRING_TOKEN(ADJUST_HELP_PAGE_UP), gHiiHandle);
29347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (HelpHeaderString != NULL) {
29357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            FreePool (HelpHeaderString);
29367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            HelpHeaderString = NULL;
29377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
29387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          HelpHeaderLine  = ProcessHelpString (StringPtr, &HelpHeaderString, &HeaderLineWidth, 0);
29397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          FreePool (StringPtr);
29407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          StringPtr       = GetToken (STRING_TOKEN(ADJUST_HELP_PAGE_DOWN), gHiiHandle);
29417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (HelpBottomString != NULL) {
29427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            FreePool (HelpBottomString);
29437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            HelpBottomString = NULL;
29447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
29457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          HelpBottomLine  = ProcessHelpString (StringPtr, &HelpBottomString, &BottomLineWidth, 0);
29467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          FreePool (StringPtr);
29477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
29487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Calculate the help page count.
29497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
29507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (HelpLine > 2 * RowCount - 2) {
29517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            HelpPageCount = (HelpLine - RowCount + 1) / (RowCount - 2) + 1;
295292f62cfe0a74eaea750104249761f207e8755e88Eric Dong            if ((HelpLine - RowCount + 1) % (RowCount - 2) != 0) {
29537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              HelpPageCount += 1;
29547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            }
29557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          } else {
29567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            HelpPageCount = 2;
29577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
29587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else {
29597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          MultiHelpPage = FALSE;
29607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
29617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
29627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
29637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
29647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Check whether need to show the 'More(U/u)' at the begin.
29657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Base on current direct info, here shows aligned to the right side of the column.
29667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // If the direction is multi line and aligned to right side may have problem, so
29677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // add ASSERT code here.
29687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
29697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (HelpPageIndex > 0) {
29707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        gST->ConOut->SetAttribute (gST->ConOut, GetInfoTextColor ());
29717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        for (Index = 0; Index < HelpHeaderLine; Index++) {
29727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ASSERT (HelpHeaderLine == 1);
29737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ASSERT (GetStringWidth (HelpHeaderString) / 2 < (UINTN) (gHelpBlockWidth - 1));
29747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          PrintStringAtWithWidth (
29757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gStatementDimensions.RightColumn - gHelpBlockWidth,
29767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Index + TopRow,
29777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gEmptyString,
29787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gHelpBlockWidth
29797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            );
29807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          PrintStringAt (
29817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gStatementDimensions.RightColumn - GetStringWidth (HelpHeaderString) / 2 - 1,
29827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Index + TopRow,
29837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            &HelpHeaderString[Index * HeaderLineWidth]
29847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            );
29857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
29867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
29877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
29887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      gST->ConOut->SetAttribute (gST->ConOut, GetHelpTextColor ());
29897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
29907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Print the help string info.
29917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
29927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (!MultiHelpPage) {
29937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        for (Index = 0; Index < HelpLine; Index++) {
29947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          PrintStringAtWithWidth (
29957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gStatementDimensions.RightColumn - gHelpBlockWidth,
29967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Index + TopRow,
29977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            &HelpString[Index * EachLineWidth],
29987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gHelpBlockWidth
29997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            );
30007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
30017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        for (; Index < RowCount; Index ++) {
30027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          PrintStringAtWithWidth (
30037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gStatementDimensions.RightColumn - gHelpBlockWidth,
30047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Index + TopRow,
30057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gEmptyString,
30067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gHelpBlockWidth
30077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            );
30087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
30097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        gST->ConOut->SetCursorPosition(gST->ConOut, gStatementDimensions.RightColumn-1, BottomRow);
30107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      } else  {
30117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (HelpPageIndex == 0) {
30127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          for (Index = 0; Index < RowCount - HelpBottomLine; Index++) {
30137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            PrintStringAtWithWidth (
30147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              gStatementDimensions.RightColumn - gHelpBlockWidth,
30157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              Index + TopRow,
30167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              &HelpString[Index * EachLineWidth],
30177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              gHelpBlockWidth
30187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              );
30197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
30207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else {
30217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          for (Index = 0; (Index < RowCount - HelpBottomLine - HelpHeaderLine) &&
30227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              (Index + HelpPageIndex * (RowCount - 2) + 1 < HelpLine); Index++) {
30237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            PrintStringAtWithWidth (
30247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              gStatementDimensions.RightColumn - gHelpBlockWidth,
30257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              Index + TopRow + HelpHeaderLine,
30267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              &HelpString[(Index + HelpPageIndex * (RowCount - 2) + 1)* EachLineWidth],
30277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              gHelpBlockWidth
30287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              );
30297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
30307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (HelpPageIndex == HelpPageCount - 1) {
30317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            for (; Index < RowCount - HelpHeaderLine; Index ++) {
30327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong              PrintStringAtWithWidth (
30337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                gStatementDimensions.RightColumn - gHelpBlockWidth,
30347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                Index + TopRow + HelpHeaderLine,
30357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                gEmptyString,
30367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                gHelpBlockWidth
30377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                );
30387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            }
30397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gST->ConOut->SetCursorPosition(gST->ConOut, gStatementDimensions.RightColumn-1, BottomRow);
30407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
30417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
30427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
30437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
30447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
30457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Check whether need to print the 'More(D/d)' at the bottom.
30467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Base on current direct info, here shows aligned to the right side of the column.
30477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // If the direction is multi line and aligned to right side may have problem, so
30487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // add ASSERT code here.
30497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
30507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (HelpPageIndex < HelpPageCount - 1 && MultiHelpPage) {
30517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        gST->ConOut->SetAttribute (gST->ConOut, GetInfoTextColor ());
30527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        for (Index = 0; Index < HelpBottomLine; Index++) {
30537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ASSERT (HelpBottomLine == 1);
30547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ASSERT (GetStringWidth (HelpBottomString) / 2 < (UINTN) (gHelpBlockWidth - 1));
30557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          PrintStringAtWithWidth (
30567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gStatementDimensions.RightColumn - gHelpBlockWidth,
30577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            BottomRow + Index - HelpBottomLine + 1,
30587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gEmptyString,
30597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gHelpBlockWidth
30607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            );
30617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          PrintStringAt (
30627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gStatementDimensions.RightColumn - GetStringWidth (HelpBottomString) / 2 - 1,
30637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            BottomRow + Index - HelpBottomLine + 1,
30647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            &HelpBottomString[Index * BottomLineWidth]
30657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            );
30667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
30677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
30687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
30697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Reset this flag every time we finish using it.
30707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
30717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Repaint = FALSE;
30727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      NewLine = FALSE;
30737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
30747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
30757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfPrepareToReadKey:
30767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfReadKey;
30777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ScreenOperation = UiNoOperation;
30787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
30797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
30807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfReadKey:
30817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfScreenOperation;
30827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
30837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
30847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Wait for user's selection
30857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
30867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      while (TRUE) {
30877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
30887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (!EFI_ERROR (Status)) {
30897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          EventType = UIEventKey;
30907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
30917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
30927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
30937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
30947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // If we encounter error, continue to read another key in.
30957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
30967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (Status != EFI_NOT_READY) {
30977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          continue;
30987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
30997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
31007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        EventType = UiWaitForEvent(gST->ConIn->WaitForKey);
31017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (EventType == UIEventKey) {
31027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
31037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
31047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
31057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
31067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
31077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (EventType == UIEventDriver) {
310842645c3dcf0488c616422dcdfd1596939223f432Eric Dong        gMisMatch = TRUE;
31097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        gUserInput->Action = BROWSER_ACTION_NONE;
31107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ControlFlag = CfExit;
31117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
31127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
31137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
31147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (EventType == UIEventTimeOut) {
31157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        gUserInput->Action = BROWSER_ACTION_FORM_EXIT;
31167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ControlFlag = CfExit;
31177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
31187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
31197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
31207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      switch (Key.UnicodeChar) {
31217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case CHAR_CARRIAGE_RETURN:
31227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if(MenuOption == NULL || MenuOption->GrayOut || MenuOption->ReadOnly) {
31237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ControlFlag = CfReadKey;
31247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
31257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
31267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
31277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ScreenOperation = UiSelect;
31287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        gDirection      = 0;
31297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
31307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
31317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
31327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // We will push the adjustment of these numeric values directly to the input handler
31337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //  NOTE: we won't handle manual input numeric
31347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
31357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case '+':
31367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case '-':
31377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
31387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // If the screen has no menu items, and the user didn't select UiReset
31397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // ignore the selection and go back to reading keys.
31407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
314105de47ef04864cd9d55228b2065d7397387e54acEric Dong        ASSERT(MenuOption != NULL);
31427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if(IsListEmpty (&gMenuOption) || MenuOption->GrayOut || MenuOption->ReadOnly) {
31437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ControlFlag = CfReadKey;
31447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
31457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
31467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
31477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Statement = MenuOption->ThisTag;
31487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP)
31497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          || (Statement->OpCode->OpCode == EFI_IFR_TIME_OP)
31507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          || ((Statement->OpCode->OpCode == EFI_IFR_NUMERIC_OP) && (GetFieldFromNum(Statement->OpCode) != 0))
31517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ){
31527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (Key.UnicodeChar == '+') {
31537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gDirection = SCAN_RIGHT;
31547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          } else {
31557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            gDirection = SCAN_LEFT;
31567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
31577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
31587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Status = ProcessOptions (MenuOption, TRUE, &OptionString, TRUE);
31597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (OptionString != NULL) {
31607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            FreePool (OptionString);
31617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
31627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (EFI_ERROR (Status)) {
31637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
31647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            // Repaint to clear possible error prompt pop-up
31657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
31667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Repaint = TRUE;
31677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            NewLine = TRUE;
31687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          } else {
31697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            ControlFlag = CfExit;
31707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
31717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
31727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
31737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
31747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case '^':
31757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ScreenOperation = UiUp;
31767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
31777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
31787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case 'V':
31797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case 'v':
31807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ScreenOperation = UiDown;
31817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
31827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
31837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case ' ':
31847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if(IsListEmpty (&gMenuOption)) {
31857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ControlFlag = CfReadKey;
31867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
31877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
31887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
31897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ASSERT(MenuOption != NULL);
31907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_CHECKBOX_OP && !MenuOption->GrayOut && !MenuOption->ReadOnly) {
31917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ScreenOperation = UiSelect;
31927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
31937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
31947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
31957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case 'D':
31967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case 'd':
31977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (!MultiHelpPage) {
31987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ControlFlag = CfReadKey;
31997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
32007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
32017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ControlFlag    = CfUpdateHelpString;
32027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        HelpPageIndex  = HelpPageIndex < HelpPageCount - 1 ? HelpPageIndex + 1 : HelpPageCount - 1;
32037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
32047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case 'U':
32067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case 'u':
32077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (!MultiHelpPage) {
32087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ControlFlag = CfReadKey;
32097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
32107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
32117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ControlFlag    = CfUpdateHelpString;
32127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        HelpPageIndex  = HelpPageIndex > 0 ? HelpPageIndex - 1 : 0;
32137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
32147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case CHAR_NULL:
32167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        for (Index = 0; Index < mScanCodeNumber; Index++) {
32177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (Key.ScanCode == gScanCodeToOperation[Index].ScanCode) {
32187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            ScreenOperation = gScanCodeToOperation[Index].ScreenOperation;
32197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            break;
32207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
32217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
32227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (((FormData->Attribute & HII_DISPLAY_MODAL) != 0) && (Key.ScanCode == SCAN_ESC || Index == mScanCodeNumber)) {
32247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
32257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // ModalForm has no ESC key and Hot Key.
32267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
32277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ControlFlag = CfReadKey;
32287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else if (Index == mScanCodeNumber) {
32297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
32307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Check whether Key matches the registered hot key.
32317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
32327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          HotKey = NULL;
32337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          HotKey = GetHotKeyFromRegisterList (&Key);
32347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (HotKey != NULL) {
32357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            ScreenOperation = UiHotKey;
32367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
32377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
32387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
32397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
32407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
32417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfScreenOperation:
32438924aecd470f84968369982a69aa30acc7c387dfEric Dong      if ((ScreenOperation != UiReset) && (ScreenOperation != UiHotKey)) {
32447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
32458924aecd470f84968369982a69aa30acc7c387dfEric Dong        // If the screen has no menu items, and the user didn't select UiReset or UiHotKey
32467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // ignore the selection and go back to reading keys.
32477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
32487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (IsListEmpty (&gMenuOption)) {
32497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ControlFlag = CfReadKey;
32507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
32517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
32527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
32537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      for (Index = 0;
32557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong           Index < sizeof (gScreenOperationToControlFlag) / sizeof (gScreenOperationToControlFlag[0]);
32567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong           Index++
32577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ) {
32587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (ScreenOperation == gScreenOperationToControlFlag[Index].ScreenOperation) {
32597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ControlFlag = gScreenOperationToControlFlag[Index].ControlFlag;
32607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
32617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
32627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
32637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
32647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUiSelect:
32667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfRepaint;
32677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT(MenuOption != NULL);
32697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Statement = MenuOption->ThisTag;
32707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) {
32717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
32727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
32737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      switch (Statement->OpCode->OpCode) {
32757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case EFI_IFR_REF_OP:
32767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case EFI_IFR_ACTION_OP:
32777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case EFI_IFR_RESET_BUTTON_OP:
32787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ControlFlag = CfExit;
32797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
32807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      default:
32827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
32837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Editable Questions: oneof, ordered list, checkbox, numeric, string, password
32847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
32857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        RefreshKeyHelp (gFormData, Statement, TRUE);
32867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Status = ProcessOptions (MenuOption, TRUE, &OptionString, TRUE);
32877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (OptionString != NULL) {
32897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          FreePool (OptionString);
32907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
32917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
32927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (EFI_ERROR (Status)) {
32937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Repaint = TRUE;
32947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          NewLine = TRUE;
32957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          RefreshKeyHelp (gFormData, Statement, FALSE);
32967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
32977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else {
32987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ControlFlag = CfExit;
32997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
33007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
33017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
33027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
33037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUiReset:
33057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
33067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // We come here when someone press ESC
33077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // If the policy is not exit front page when user press ESC, process here.
33087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
33097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (!FormExitPolicy()) {
33107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Repaint     = TRUE;
33117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        NewLine     = TRUE;
33127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ControlFlag = CfRepaint;
33137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
33147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
33157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      gUserInput->Action = BROWSER_ACTION_FORM_EXIT;
33177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfExit;
33187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
33197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUiHotKey:
33217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfRepaint;
332205de47ef04864cd9d55228b2065d7397387e54acEric Dong
332305de47ef04864cd9d55228b2065d7397387e54acEric Dong      ASSERT (HotKey != NULL);
332423c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
332523c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong      if (FxConfirmPopup(HotKey->Action)) {
332623c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong        gUserInput->Action = HotKey->Action;
3327a687a1d207f1b84e08f2a45fcbc0c0d8f0763214Eric Dong        if ((HotKey->Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {
3328a687a1d207f1b84e08f2a45fcbc0c0d8f0763214Eric Dong          gUserInput->DefaultId = HotKey->DefaultId;
3329a687a1d207f1b84e08f2a45fcbc0c0d8f0763214Eric Dong        }
333023c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong        ControlFlag = CfExit;
333123c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong      } else {
333223c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong        Repaint     = TRUE;
333323c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong        NewLine     = TRUE;
333423c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong        ControlFlag = CfRepaint;
333523c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong      }
333623c7d4258f3a916c916f16e1cdf4c217a539b984Eric Dong
33377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
33387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUiLeft:
33407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfRepaint;
33417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT(MenuOption != NULL);
33427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)) {
33437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (MenuOption->Sequence != 0) {
33447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
33457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // In the middle or tail of the Date/Time op-code set, go left.
33467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
33477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ASSERT(NewPos != NULL);
33487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          NewPos = NewPos->BackLink;
33497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
33507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
33517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
33527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUiRight:
33547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfRepaint;
33557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT(MenuOption != NULL);
33567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)) {
33577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (MenuOption->Sequence != 2) {
33587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
33597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // In the middle or tail of the Date/Time op-code set, go left.
33607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
33617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ASSERT(NewPos != NULL);
33627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          NewPos = NewPos->ForwardLink;
33637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
33647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
33657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
33667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUiUp:
33687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfRepaint;
3369ab369468265cd29a90b385a6e950eda3da16636dEric Dong      NewLine     = TRUE;
33707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
33717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      SavedListEntry = NewPos;
33727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT(NewPos != NULL);
3373f0c5095b274b2b35867d5245119aa1aba0acc87eEric Dong
3374f0c5095b274b2b35867d5245119aa1aba0acc87eEric Dong      MenuOption = MENU_OPTION_FROM_LINK (NewPos);
3375f0c5095b274b2b35867d5245119aa1aba0acc87eEric Dong      ASSERT (MenuOption != NULL);
3376f0c5095b274b2b35867d5245119aa1aba0acc87eEric Dong
33777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
33787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Adjust Date/Time position before we advance forward.
33797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
33807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      AdjustDateAndTimePosition (TRUE, &NewPos);
33817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3382ab369468265cd29a90b385a6e950eda3da16636dEric Dong      NewPos     = NewPos->BackLink;
3383ab369468265cd29a90b385a6e950eda3da16636dEric Dong      //
3384ab369468265cd29a90b385a6e950eda3da16636dEric Dong      // Find next selectable menu or the first menu beyond current form.
3385ab369468265cd29a90b385a6e950eda3da16636dEric Dong      //
3386ab369468265cd29a90b385a6e950eda3da16636dEric Dong      Difference = MoveToNextStatement (TRUE, &NewPos, MenuOption->Row - TopRow, FALSE);
3387ab369468265cd29a90b385a6e950eda3da16636dEric Dong      if (Difference < 0) {
3388ab369468265cd29a90b385a6e950eda3da16636dEric Dong        //
3389ab369468265cd29a90b385a6e950eda3da16636dEric Dong        // We hit the begining MenuOption that can be focused
3390ab369468265cd29a90b385a6e950eda3da16636dEric Dong        // so we simply scroll to the top.
3391ab369468265cd29a90b385a6e950eda3da16636dEric Dong        //
3392ab369468265cd29a90b385a6e950eda3da16636dEric Dong        Repaint     = TRUE;
3393ab369468265cd29a90b385a6e950eda3da16636dEric Dong        if (TopOfScreen != gMenuOption.ForwardLink || SkipValue != 0) {
3394ab369468265cd29a90b385a6e950eda3da16636dEric Dong          TopOfScreen = gMenuOption.ForwardLink;
3395ab369468265cd29a90b385a6e950eda3da16636dEric Dong          NewPos      = SavedListEntry;
3396ab369468265cd29a90b385a6e950eda3da16636dEric Dong          SkipValue = 0;
3397ab369468265cd29a90b385a6e950eda3da16636dEric Dong        } else {
33987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
3399ab369468265cd29a90b385a6e950eda3da16636dEric Dong          // Scroll up to the last page when we have arrived at top page.
34007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
3401ab369468265cd29a90b385a6e950eda3da16636dEric Dong          TopOfScreen = FindTopOfScreenMenu (gMenuOption.BackLink, BottomRow - TopRow, &SkipValue);
3402ab369468265cd29a90b385a6e950eda3da16636dEric Dong          NewPos = gMenuOption.BackLink;
3403ab369468265cd29a90b385a6e950eda3da16636dEric Dong          MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow, TRUE);
3404ab369468265cd29a90b385a6e950eda3da16636dEric Dong        }
3405ab369468265cd29a90b385a6e950eda3da16636dEric Dong      } else {
3406ab369468265cd29a90b385a6e950eda3da16636dEric Dong        NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
3407ab369468265cd29a90b385a6e950eda3da16636dEric Dong
3408ab369468265cd29a90b385a6e950eda3da16636dEric Dong        if (MenuOption->Row < TopRow + Difference + NextMenuOption->Skip) {
34097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
34107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Previous focus MenuOption is above the TopOfScreen, so we need to scroll
34117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
34127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          TopOfScreen = NewPos;
34137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Repaint     = TRUE;
3414ab369468265cd29a90b385a6e950eda3da16636dEric Dong          SkipValue   = 0;
34157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
34167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
34177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
3418ab369468265cd29a90b385a6e950eda3da16636dEric Dong        // Check whether new highlight menu is selectable, if not, keep highlight on the old one.
34197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
3420ab369468265cd29a90b385a6e950eda3da16636dEric Dong        // BottomRow - TopRow + 1 means the total rows current forms supported.
3421ab369468265cd29a90b385a6e950eda3da16636dEric Dong        // Difference + NextMenuOption->Skip + 1 means the distance between last highlight menu
3422ab369468265cd29a90b385a6e950eda3da16636dEric Dong        // and new top menu. New top menu will all shows in next form, but last highlight menu
3423ab369468265cd29a90b385a6e950eda3da16636dEric Dong        // may only shows 1 line. + 1 at right part means at least need to keep 1 line for the
3424ab369468265cd29a90b385a6e950eda3da16636dEric Dong        // last highlight menu.
3425ab369468265cd29a90b385a6e950eda3da16636dEric Dong        //
3426ab369468265cd29a90b385a6e950eda3da16636dEric Dong        if (!IsSelectable(NextMenuOption) && IsSelectable(MenuOption) &&
3427ab369468265cd29a90b385a6e950eda3da16636dEric Dong            (BottomRow - TopRow + 1 >= Difference + NextMenuOption->Skip + 1)) {
3428ab369468265cd29a90b385a6e950eda3da16636dEric Dong          NewPos = SavedListEntry;
34296f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong        }
34307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
34317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3432ab369468265cd29a90b385a6e950eda3da16636dEric Dong      UpdateStatusBar (INPUT_ERROR, FALSE);
34337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
34347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
3435ab369468265cd29a90b385a6e950eda3da16636dEric Dong      // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
34367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
3437ab369468265cd29a90b385a6e950eda3da16636dEric Dong      AdjustDateAndTimePosition (TRUE, &TopOfScreen);
3438ab369468265cd29a90b385a6e950eda3da16636dEric Dong      AdjustDateAndTimePosition (TRUE, &NewPos);
343942645c3dcf0488c616422dcdfd1596939223f432Eric Dong
344042645c3dcf0488c616422dcdfd1596939223f432Eric Dong      UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);
3441ab369468265cd29a90b385a6e950eda3da16636dEric Dong      break;
34427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3443ab369468265cd29a90b385a6e950eda3da16636dEric Dong    case CfUiPageUp:
34447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
3445ab369468265cd29a90b385a6e950eda3da16636dEric Dong      // SkipValue means lines is skipped when show the top menu option.
34467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
3447ab369468265cd29a90b385a6e950eda3da16636dEric Dong      ControlFlag = CfRepaint;
3448ab369468265cd29a90b385a6e950eda3da16636dEric Dong      NewLine     = TRUE;
3449ab369468265cd29a90b385a6e950eda3da16636dEric Dong      Repaint     = TRUE;
34507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
34517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Link      = TopOfScreen;
34527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
34537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // First minus the menu of the top screen, it's value is SkipValue.
34547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
34552e7183ba91b90ac0a257a206080fe84849887cdcEric Dong      if (SkipValue >= BottomRow - TopRow + 1) {
34567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
3457ab369468265cd29a90b385a6e950eda3da16636dEric Dong        // SkipValue > (BottomRow - TopRow + 1) means current menu has more than one
3458ab369468265cd29a90b385a6e950eda3da16636dEric Dong        // form of options to be show, so just update the SkipValue to show the next
3459ab369468265cd29a90b385a6e950eda3da16636dEric Dong        // parts of options.
34607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
3461ab369468265cd29a90b385a6e950eda3da16636dEric Dong        SkipValue -= BottomRow - TopRow + 1;
3462ab369468265cd29a90b385a6e950eda3da16636dEric Dong        NewPos     = TopOfScreen;
3463ab369468265cd29a90b385a6e950eda3da16636dEric Dong        break;
3464ab369468265cd29a90b385a6e950eda3da16636dEric Dong      } else {
3465ab369468265cd29a90b385a6e950eda3da16636dEric Dong        Index     = (BottomRow + 1) - SkipValue - TopRow;
34667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
3467ab369468265cd29a90b385a6e950eda3da16636dEric Dong
3468ab369468265cd29a90b385a6e950eda3da16636dEric Dong      TopOfScreen = FindTopOfScreenMenu(TopOfScreen, Index, &SkipValue);
3469ab369468265cd29a90b385a6e950eda3da16636dEric Dong      NewPos = TopOfScreen;
3470ab369468265cd29a90b385a6e950eda3da16636dEric Dong      MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow, FALSE);
3471ab369468265cd29a90b385a6e950eda3da16636dEric Dong
3472ab369468265cd29a90b385a6e950eda3da16636dEric Dong      UpdateStatusBar (INPUT_ERROR, FALSE);
34737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
34747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
34757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
34767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Don't do this when we are already in the first page.
34777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
34787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      AdjustDateAndTimePosition (TRUE, &TopOfScreen);
34797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      AdjustDateAndTimePosition (TRUE, &NewPos);
348042645c3dcf0488c616422dcdfd1596939223f432Eric Dong
348142645c3dcf0488c616422dcdfd1596939223f432Eric Dong      UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);
34827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
34837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
34847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUiPageDown:
34857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
34867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // SkipValue means lines is skipped when show the top menu option.
34877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
3488ab369468265cd29a90b385a6e950eda3da16636dEric Dong      ControlFlag = CfRepaint;
3489ab369468265cd29a90b385a6e950eda3da16636dEric Dong      NewLine     = TRUE;
3490ab369468265cd29a90b385a6e950eda3da16636dEric Dong      Repaint     = TRUE;
34917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
34927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Link    = TopOfScreen;
34937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      NextMenuOption = MENU_OPTION_FROM_LINK (Link);
34947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Index = TopRow + NextMenuOption->Skip - SkipValue;
34957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
34967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Count to the menu option which will show at the top of the next form.
34977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
34987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      while ((Index <= BottomRow + 1) && (Link->ForwardLink != &gMenuOption)) {
34997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Link           = Link->ForwardLink;
35007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        NextMenuOption = MENU_OPTION_FROM_LINK (Link);
35017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Index = Index + NextMenuOption->Skip;
35027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
35037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
35047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if ((Link->ForwardLink == &gMenuOption) && (Index <= BottomRow + 1)) {
35057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
3506ab369468265cd29a90b385a6e950eda3da16636dEric Dong        // Highlight on the last menu which can be highlight.
35077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
35087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Repaint = FALSE;
3509ab369468265cd29a90b385a6e950eda3da16636dEric Dong        MoveToNextStatement (TRUE, &Link, Index - TopRow, TRUE);
35107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      } else {
35117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
35127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Calculate the skip line for top of screen menu.
35137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
35147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (Link == TopOfScreen) {
35157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
35167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // The top of screen menu option occupies the entire form.
35177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
35187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          SkipValue += BottomRow - TopRow + 1;
35197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else {
35207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          SkipValue = NextMenuOption->Skip - (Index - (BottomRow + 1));
35217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
35227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        TopOfScreen = Link;
35237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        MenuOption = NULL;
35247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
35257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Move to the Next selectable menu.
35267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
3527ab369468265cd29a90b385a6e950eda3da16636dEric Dong        MoveToNextStatement (FALSE, &Link, BottomRow - TopRow, TRUE);
35287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
35297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
35307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
35317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Save the menu as the next highlight menu.
35327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
35337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      NewPos  = Link;
35347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3535ab369468265cd29a90b385a6e950eda3da16636dEric Dong      UpdateStatusBar (INPUT_ERROR, FALSE);
3536ab369468265cd29a90b385a6e950eda3da16636dEric Dong
35377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
35387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
35397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Don't do this when we are already in the last page.
35407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
35417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      AdjustDateAndTimePosition (TRUE, &TopOfScreen);
35427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      AdjustDateAndTimePosition (TRUE, &NewPos);
354342645c3dcf0488c616422dcdfd1596939223f432Eric Dong
354442645c3dcf0488c616422dcdfd1596939223f432Eric Dong      UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);
35457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
35467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
35477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUiDown:
35487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
35497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // SkipValue means lines is skipped when show the top menu option.
35507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // NewPos  points to the menu which is highlighted now.
35517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
35527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfRepaint;
3553ab369468265cd29a90b385a6e950eda3da16636dEric Dong      NewLine     = TRUE;
35547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3555ab369468265cd29a90b385a6e950eda3da16636dEric Dong      if (NewPos == TopOfScreen) {
3556ab369468265cd29a90b385a6e950eda3da16636dEric Dong        Temp2 = SkipValue;
3557ab369468265cd29a90b385a6e950eda3da16636dEric Dong      } else {
3558ab369468265cd29a90b385a6e950eda3da16636dEric Dong        Temp2 = 0;
3559ab369468265cd29a90b385a6e950eda3da16636dEric Dong      }
3560ab369468265cd29a90b385a6e950eda3da16636dEric Dong
3561ab369468265cd29a90b385a6e950eda3da16636dEric Dong      SavedListEntry = NewPos;
35627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
35637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Since the behavior of hitting the down arrow on a Date/Time op-code is intended
35647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // to be one that progresses to the next set of op-codes, we need to advance to the last
35657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Date/Time op-code and leave the remaining logic in UiDown intact so the appropriate
35667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // checking can be done.  The only other logic we need to introduce is that if a Date/Time
35677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // op-code is the last entry in the menu, we need to rewind back to the first op-code of
35687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // the Date/Time op-code.
35697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
35707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      AdjustDateAndTimePosition (FALSE, &NewPos);
35717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3572ab369468265cd29a90b385a6e950eda3da16636dEric Dong      MenuOption = MENU_OPTION_FROM_LINK (NewPos);
3573ab369468265cd29a90b385a6e950eda3da16636dEric Dong      NewPos     = NewPos->ForwardLink;
3574ab369468265cd29a90b385a6e950eda3da16636dEric Dong      //
3575ab369468265cd29a90b385a6e950eda3da16636dEric Dong      // Find the next selectable menu.
3576ab369468265cd29a90b385a6e950eda3da16636dEric Dong      //
3577ab369468265cd29a90b385a6e950eda3da16636dEric Dong      if (MenuOption->Row + MenuOption->Skip - Temp2 > BottomRow + 1) {
3578ab369468265cd29a90b385a6e950eda3da16636dEric Dong        if (gMenuOption.ForwardLink == NewPos || &gMenuOption == NewPos) {
3579ab369468265cd29a90b385a6e950eda3da16636dEric Dong          Difference = -1;
3580ab369468265cd29a90b385a6e950eda3da16636dEric Dong        } else {
3581ab369468265cd29a90b385a6e950eda3da16636dEric Dong          Difference = 0;
3582ab369468265cd29a90b385a6e950eda3da16636dEric Dong        }
3583ab369468265cd29a90b385a6e950eda3da16636dEric Dong      } else {
3584ab369468265cd29a90b385a6e950eda3da16636dEric Dong        Difference = MoveToNextStatement (FALSE, &NewPos, BottomRow + 1 - (MenuOption->Row + MenuOption->Skip - Temp2), FALSE);
3585ab369468265cd29a90b385a6e950eda3da16636dEric Dong      }
3586ab369468265cd29a90b385a6e950eda3da16636dEric Dong      if (Difference < 0) {
3587ab369468265cd29a90b385a6e950eda3da16636dEric Dong        //
3588ab369468265cd29a90b385a6e950eda3da16636dEric Dong        // Scroll to the first page.
3589ab369468265cd29a90b385a6e950eda3da16636dEric Dong        //
3590ab369468265cd29a90b385a6e950eda3da16636dEric Dong        if (TopOfScreen != gMenuOption.ForwardLink || SkipValue != 0) {
3591ab369468265cd29a90b385a6e950eda3da16636dEric Dong          TopOfScreen = gMenuOption.ForwardLink;
3592ab369468265cd29a90b385a6e950eda3da16636dEric Dong          Repaint     = TRUE;
3593ab369468265cd29a90b385a6e950eda3da16636dEric Dong          MenuOption  = NULL;
35946f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong        } else {
3595ab369468265cd29a90b385a6e950eda3da16636dEric Dong          MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
35966f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong        }
3597ab369468265cd29a90b385a6e950eda3da16636dEric Dong        NewPos        = gMenuOption.ForwardLink;
3598ab369468265cd29a90b385a6e950eda3da16636dEric Dong        MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow, TRUE);
35996f05c02325fff475d695edacd0b0b003e5b1fcf3Eric Dong
3600ab369468265cd29a90b385a6e950eda3da16636dEric Dong        SkipValue = 0;
3601ab369468265cd29a90b385a6e950eda3da16636dEric Dong        //
3602ab369468265cd29a90b385a6e950eda3da16636dEric Dong        // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
3603ab369468265cd29a90b385a6e950eda3da16636dEric Dong        //
3604ab369468265cd29a90b385a6e950eda3da16636dEric Dong        AdjustDateAndTimePosition (TRUE, &TopOfScreen);
3605ab369468265cd29a90b385a6e950eda3da16636dEric Dong        AdjustDateAndTimePosition (TRUE, &NewPos);
360642645c3dcf0488c616422dcdfd1596939223f432Eric Dong
360742645c3dcf0488c616422dcdfd1596939223f432Eric Dong        UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);
3608ab369468265cd29a90b385a6e950eda3da16636dEric Dong        break;
3609ab369468265cd29a90b385a6e950eda3da16636dEric Dong      }
36107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3611ab369468265cd29a90b385a6e950eda3da16636dEric Dong      //
3612ab369468265cd29a90b385a6e950eda3da16636dEric Dong      // Get next selected menu info.
3613ab369468265cd29a90b385a6e950eda3da16636dEric Dong      //
3614ab369468265cd29a90b385a6e950eda3da16636dEric Dong      AdjustDateAndTimePosition (FALSE, &NewPos);
3615ab369468265cd29a90b385a6e950eda3da16636dEric Dong      NextMenuOption  = MENU_OPTION_FROM_LINK (NewPos);
3616ab369468265cd29a90b385a6e950eda3da16636dEric Dong      if (NextMenuOption->Row == 0) {
3617ab369468265cd29a90b385a6e950eda3da16636dEric Dong        UpdateOptionSkipLines (NextMenuOption);
3618ab369468265cd29a90b385a6e950eda3da16636dEric Dong      }
3619ab369468265cd29a90b385a6e950eda3da16636dEric Dong
3620ab369468265cd29a90b385a6e950eda3da16636dEric Dong      //
3621ab369468265cd29a90b385a6e950eda3da16636dEric Dong      // Calculate new highlight menu end row.
3622ab369468265cd29a90b385a6e950eda3da16636dEric Dong      //
3623ab369468265cd29a90b385a6e950eda3da16636dEric Dong      Temp = (MenuOption->Row + MenuOption->Skip - Temp2) + Difference + NextMenuOption->Skip - 1;
3624ab369468265cd29a90b385a6e950eda3da16636dEric Dong      if (Temp > BottomRow) {
36257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
3626ab369468265cd29a90b385a6e950eda3da16636dEric Dong        // Get the top screen menu info.
36277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
3628ab369468265cd29a90b385a6e950eda3da16636dEric Dong        AdjustDateAndTimePosition (FALSE, &TopOfScreen);
3629ab369468265cd29a90b385a6e950eda3da16636dEric Dong        SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
3630ab369468265cd29a90b385a6e950eda3da16636dEric Dong
3631ab369468265cd29a90b385a6e950eda3da16636dEric Dong        //
3632ab369468265cd29a90b385a6e950eda3da16636dEric Dong        // Current Top screen menu occupy (SavedMenuOption->Skip - SkipValue) rows.
3633ab369468265cd29a90b385a6e950eda3da16636dEric Dong        // Full shows the new selected menu need to skip (Temp - BottomRow - 1) rows.
3634ab369468265cd29a90b385a6e950eda3da16636dEric Dong        //
3635ab369468265cd29a90b385a6e950eda3da16636dEric Dong        if ((Temp - BottomRow) >= (SavedMenuOption->Skip - SkipValue)) {
36367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
3637ab369468265cd29a90b385a6e950eda3da16636dEric Dong          // Skip the top op-code
36387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
3639ab369468265cd29a90b385a6e950eda3da16636dEric Dong          TopOfScreen   = TopOfScreen->ForwardLink;
3640ab369468265cd29a90b385a6e950eda3da16636dEric Dong          DistanceValue = (Temp - BottomRow) - (SavedMenuOption->Skip - SkipValue);
36417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3642ab369468265cd29a90b385a6e950eda3da16636dEric Dong          SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
36437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3644ab369468265cd29a90b385a6e950eda3da16636dEric Dong          //
3645ab369468265cd29a90b385a6e950eda3da16636dEric Dong          // If we have a remainder, skip that many more op-codes until we drain the remainder
3646ab369468265cd29a90b385a6e950eda3da16636dEric Dong          // Special case is the selected highlight menu has more than one form of menus.
3647ab369468265cd29a90b385a6e950eda3da16636dEric Dong          //
3648ab369468265cd29a90b385a6e950eda3da16636dEric Dong          while (DistanceValue >= SavedMenuOption->Skip && TopOfScreen != NewPos) {
36497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
3650ab369468265cd29a90b385a6e950eda3da16636dEric Dong            // Since the Difference is greater than or equal to this op-code's skip value, skip it
36517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
3652ab369468265cd29a90b385a6e950eda3da16636dEric Dong            DistanceValue   = DistanceValue - (INTN) SavedMenuOption->Skip;
3653ab369468265cd29a90b385a6e950eda3da16636dEric Dong            TopOfScreen     = TopOfScreen->ForwardLink;
36547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
3655ab369468265cd29a90b385a6e950eda3da16636dEric Dong          }
36567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
3657ab369468265cd29a90b385a6e950eda3da16636dEric Dong          // Since we will act on this op-code in the next routine, and increment the
3658ab369468265cd29a90b385a6e950eda3da16636dEric Dong          // SkipValue, set the skips to one less than what is required.
36597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
3660ab369468265cd29a90b385a6e950eda3da16636dEric Dong          if (TopOfScreen != NewPos) {
3661ab369468265cd29a90b385a6e950eda3da16636dEric Dong            SkipValue = DistanceValue;
3662ab369468265cd29a90b385a6e950eda3da16636dEric Dong          } else {
3663ab369468265cd29a90b385a6e950eda3da16636dEric Dong            SkipValue = 0;
3664ab369468265cd29a90b385a6e950eda3da16636dEric Dong          }
36657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else {
36667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
3667ab369468265cd29a90b385a6e950eda3da16636dEric Dong          // Since we will act on this op-code in the next routine, and increment the
3668ab369468265cd29a90b385a6e950eda3da16636dEric Dong          // SkipValue, set the skips to one less than what is required.
36697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
3670ab369468265cd29a90b385a6e950eda3da16636dEric Dong          SkipValue += Temp - BottomRow;
36717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
3672ab369468265cd29a90b385a6e950eda3da16636dEric Dong        Repaint       = TRUE;
3673ab369468265cd29a90b385a6e950eda3da16636dEric Dong      } else if (!IsSelectable (NextMenuOption)) {
36747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
3675ab369468265cd29a90b385a6e950eda3da16636dEric Dong        // Continue to go down until scroll to next page or the selectable option is found.
36767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
3677ab369468265cd29a90b385a6e950eda3da16636dEric Dong        ScreenOperation = UiDown;
3678ab369468265cd29a90b385a6e950eda3da16636dEric Dong        ControlFlag     = CfScreenOperation;
3679ab369468265cd29a90b385a6e950eda3da16636dEric Dong        break;
3680ab369468265cd29a90b385a6e950eda3da16636dEric Dong      }
3681ab369468265cd29a90b385a6e950eda3da16636dEric Dong
3682ab369468265cd29a90b385a6e950eda3da16636dEric Dong      MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
3683ab369468265cd29a90b385a6e950eda3da16636dEric Dong
3684ab369468265cd29a90b385a6e950eda3da16636dEric Dong      //
3685ab369468265cd29a90b385a6e950eda3da16636dEric Dong      // Check whether new highlight menu is selectable, if not, keep highlight on the old one.
3686ab369468265cd29a90b385a6e950eda3da16636dEric Dong      //
3687ab369468265cd29a90b385a6e950eda3da16636dEric Dong      // BottomRow - TopRow + 1 means the total rows current forms supported.
3688ab369468265cd29a90b385a6e950eda3da16636dEric Dong      // Difference + NextMenuOption->Skip + 1 means the distance between last highlight menu
3689ab369468265cd29a90b385a6e950eda3da16636dEric Dong      // and new top menu. New top menu will all shows in next form, but last highlight menu
3690ab369468265cd29a90b385a6e950eda3da16636dEric Dong      // may only shows 1 line. + 1 at right part means at least need to keep 1 line for the
3691ab369468265cd29a90b385a6e950eda3da16636dEric Dong      // last highlight menu.
3692ab369468265cd29a90b385a6e950eda3da16636dEric Dong      //
3693ab369468265cd29a90b385a6e950eda3da16636dEric Dong      if (!IsSelectable (NextMenuOption) && IsSelectable (MenuOption) &&
3694ab369468265cd29a90b385a6e950eda3da16636dEric Dong         (BottomRow - TopRow + 1 >= Difference + NextMenuOption->Skip + 1)) {
3695ab369468265cd29a90b385a6e950eda3da16636dEric Dong        NewPos = SavedListEntry;
36967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
36977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3698ab369468265cd29a90b385a6e950eda3da16636dEric Dong      UpdateStatusBar (INPUT_ERROR, FALSE);
3699ab369468265cd29a90b385a6e950eda3da16636dEric Dong
37007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
37017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
37027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
37037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      AdjustDateAndTimePosition (TRUE, &TopOfScreen);
37047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      AdjustDateAndTimePosition (TRUE, &NewPos);
370542645c3dcf0488c616422dcdfd1596939223f432Eric Dong
370642645c3dcf0488c616422dcdfd1596939223f432Eric Dong      UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);
37077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
37087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
37097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfUiNoOperation:
37107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ControlFlag = CfRepaint;
37117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
37127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
37137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case CfExit:
37145a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong      gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
37157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (HelpString != NULL) {
37167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        FreePool (HelpString);
37177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
37187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (HelpHeaderString != NULL) {
37197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        FreePool (HelpHeaderString);
37207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
37217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (HelpBottomString != NULL) {
37227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        FreePool (HelpBottomString);
37237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
37247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      return EFI_SUCCESS;
37257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
37267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    default:
37277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
37287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
37297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
37307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
37317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
37327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
37337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
37347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Base on the browser status info to show an pop up message.
37357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
37367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
37377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
37387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongBrowserStatusProcess (
37397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  VOID
37407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
37417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
3742bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  CHAR16             *ErrorInfo;
3743bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  EFI_INPUT_KEY      Key;
3744bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  EFI_EVENT          WaitList[2];
3745bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  EFI_EVENT          RefreshIntervalEvent;
3746bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  EFI_EVENT          TimeOutEvent;
3747bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  UINT8              TimeOut;
3748bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  EFI_STATUS         Status;
3749bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  UINTN              Index;
3750bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  WARNING_IF_CONTEXT EventContext;
3751bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  EFI_IFR_OP_HEADER  *OpCodeBuf;
3752bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  EFI_STRING_ID      StringToken;
37534d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong  CHAR16             DiscardChange;
37544d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong  CHAR16             JumpToFormSet;
37554d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong  CHAR16             *PrintString;
37567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
37577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (gFormData->BrowserStatus == BROWSER_SUCCESS) {
37587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return;
37597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
37607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3761bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  StringToken          = 0;
3762bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  TimeOutEvent         = NULL;
3763bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  RefreshIntervalEvent = NULL;
3764bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  OpCodeBuf            = NULL;
3765bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  if (gFormData->HighLightedStatement != NULL) {
3766bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong    OpCodeBuf = gFormData->HighLightedStatement->OpCode;
3767bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  }
3768bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong
3769bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  if (gFormData->BrowserStatus == (BROWSER_WARNING_IF)) {
3770bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong    ASSERT (OpCodeBuf != NULL && OpCodeBuf->OpCode == EFI_IFR_WARNING_IF_OP);
3771bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong
3772bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong    TimeOut     = ((EFI_IFR_WARNING_IF *) OpCodeBuf)->TimeOut;
3773bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong    StringToken = ((EFI_IFR_WARNING_IF *) OpCodeBuf)->Warning;
3774bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  } else {
3775bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong    TimeOut = 0;
3776bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong    if ((gFormData->BrowserStatus == (BROWSER_NO_SUBMIT_IF)) &&
3777bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong        (OpCodeBuf != NULL && OpCodeBuf->OpCode == EFI_IFR_NO_SUBMIT_IF_OP)) {
3778bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong      StringToken = ((EFI_IFR_NO_SUBMIT_IF *) OpCodeBuf)->Error;
3779bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong    } else if ((gFormData->BrowserStatus == (BROWSER_INCONSISTENT_IF)) &&
3780bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong               (OpCodeBuf != NULL && OpCodeBuf->OpCode == EFI_IFR_INCONSISTENT_IF_OP)) {
3781bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong      StringToken = ((EFI_IFR_INCONSISTENT_IF *) OpCodeBuf)->Error;
3782bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong    }
3783bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  }
3784bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong
3785bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  if (StringToken != 0) {
3786bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong    ErrorInfo = GetToken (StringToken, gFormData->HiiHandle);
3787bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  } else if (gFormData->ErrorString != NULL) {
3788bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong    //
3789bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong    // Only used to compatible with old setup browser.
3790bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong    // Not use this field in new browser core.
3791bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong    //
37927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ErrorInfo = gFormData->ErrorString;
37937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else {
37947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    switch (gFormData->BrowserStatus) {
37957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case BROWSER_SUBMIT_FAIL:
37967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ErrorInfo = gSaveFailed;
37977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
37987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
37997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case BROWSER_FORM_NOT_FOUND:
38007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ErrorInfo = gFormNotFound;
38017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
38027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
38037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case BROWSER_FORM_SUPPRESS:
38047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ErrorInfo = gFormSuppress;
38057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
38067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
38077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case BROWSER_PROTOCOL_NOT_FOUND:
38087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ErrorInfo = gProtocolNotFound;
38097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
38107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
38114d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong    case BROWSER_SUBMIT_FAIL_NO_SUBMIT_IF:
38124d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      ErrorInfo = gNoSubmitIfFailed;
38134d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      break;
38144d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong
3815f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong    case BROWSER_RECONNECT_FAIL:
3816f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong      ErrorInfo = gReconnectFail;
3817f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong      break;
3818f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong
3819f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong    case BROWSER_RECONNECT_SAVE_CHANGES:
3820f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong      ErrorInfo = gReconnectConfirmChanges;
3821f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong      break;
3822f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong
3823f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong    case BROWSER_RECONNECT_REQUIRED:
3824f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong      ErrorInfo = gReconnectRequired;
3825f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong      break;
3826f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong
38277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    default:
3828f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong      ErrorInfo = gBrowserError;
38297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
38307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
38317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
38327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
38334d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong  switch (gFormData->BrowserStatus) {
38344d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong  case BROWSER_SUBMIT_FAIL:
38354d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong  case BROWSER_SUBMIT_FAIL_NO_SUBMIT_IF:
3836f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong  case BROWSER_RECONNECT_SAVE_CHANGES:
38374d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong    ASSERT (gUserInput != NULL);
38384d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong    if (gFormData->BrowserStatus == (BROWSER_SUBMIT_FAIL)) {
38394d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      PrintString = gSaveProcess;
38404d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      JumpToFormSet = gJumpToFormSet[0];
3841f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong      DiscardChange = gDiscardChange[0];
3842f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong    } else if (gFormData->BrowserStatus == (BROWSER_RECONNECT_SAVE_CHANGES)){
3843f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong      PrintString = gChangesOpt;
3844f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong      JumpToFormSet = gConfirmOptYes[0];
3845f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong      DiscardChange = gConfirmOptNo[0];
38464d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong    } else {
38474d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      PrintString = gSaveNoSubmitProcess;
38484d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      JumpToFormSet = gCheckError[0];
3849f2e7732e446f9120e83673abb2c701aa7cba17f7Eric Dong      DiscardChange = gDiscardChange[0];
38504d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong    }
38514d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong
3852bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong    do {
38534d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      CreateDialog (&Key, gEmptyString, ErrorInfo, PrintString, gEmptyString, NULL);
38544d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong    } while (((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (DiscardChange | UPPER_LOWER_CASE_OFFSET)) &&
38554d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong             ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (JumpToFormSet | UPPER_LOWER_CASE_OFFSET)));
3856bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong
38574d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong    if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (DiscardChange | UPPER_LOWER_CASE_OFFSET)) {
38584d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      gUserInput->Action = BROWSER_ACTION_DISCARD;
38594d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong    } else {
38604d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      gUserInput->Action = BROWSER_ACTION_GOTO;
38614d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong    }
38624d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong    break;
3863bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong
38644d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong  default:
38654d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong    if (TimeOut == 0) {
38664d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      do {
38674d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong        CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL);
38684d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
38694d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong    } else {
38704d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      Status = gBS->CreateEvent (EVT_NOTIFY_WAIT, TPL_CALLBACK, EmptyEventProcess, NULL, &TimeOutEvent);
38714d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      ASSERT_EFI_ERROR (Status);
3872bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong
38734d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      EventContext.SyncEvent = TimeOutEvent;
38744d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      EventContext.TimeOut   = &TimeOut;
38754d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      EventContext.ErrorInfo = ErrorInfo;
3876bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong
38774d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, RefreshTimeOutProcess, &EventContext, &RefreshIntervalEvent);
38784d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      ASSERT_EFI_ERROR (Status);
3879bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong
38804d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      //
38814d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      // Show the dialog first to avoid long time not reaction.
38824d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      //
38834d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      gBS->SignalEvent (RefreshIntervalEvent);
38844d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong
38854d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      Status = gBS->SetTimer (RefreshIntervalEvent, TimerPeriodic, ONE_SECOND);
38864d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      ASSERT_EFI_ERROR (Status);
3887bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong
38884d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      while (TRUE) {
38894d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong        Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
38904d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong        if (!EFI_ERROR (Status) && Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
38914d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong          break;
38924d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong        }
3893bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong
38944d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong        if (Status != EFI_NOT_READY) {
38954d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong          continue;
38964d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong        }
3897bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong
38984d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong        WaitList[0] = TimeOutEvent;
38994d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong        WaitList[1] = gST->ConIn->WaitForKey;
3900bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong
39014d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong        Status = gBS->WaitForEvent (2, WaitList, &Index);
39024d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong        ASSERT_EFI_ERROR (Status);
39034d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong
39044d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong        if (Index == 0) {
39054d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong          //
39064d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong          // Timeout occur, close the hoot time out event.
39074d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong          //
39084d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong          break;
39094d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong        }
3910bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong      }
39114d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong
39124d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      gBS->CloseEvent (TimeOutEvent);
39134d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong      gBS->CloseEvent (RefreshIntervalEvent);
3914bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong    }
39154d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong    break;
3916bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  }
3917bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong
3918bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  if (StringToken != 0) {
3919bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong    FreePool (ErrorInfo);
3920bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong  }
39217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
39227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
39237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
39247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Display one form, and return user input.
39257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
39267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param FormData                Form Data to be shown.
39277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param UserInputData           User input data.
39287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
39297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval EFI_SUCCESS            1.Form Data is shown, and user input is got.
39307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                                 2.Error info has show and return.
39317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval EFI_INVALID_PARAMETER  The input screen dimension is not valid
39327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval EFI_NOT_FOUND          New form data has some error.
39337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
39347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFI_STATUS
39357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFIAPI
39367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongFormDisplay (
39377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  FORM_DISPLAY_ENGINE_FORM  *FormData,
39387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OUT USER_INPUT                *UserInputData
39397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
39407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
39417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_STATUS  Status;
39427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
39437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT (FormData != NULL);
39447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (FormData == NULL) {
39457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return EFI_INVALID_PARAMETER;
39467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
39477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
39487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gUserInput = UserInputData;
39497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gFormData  = FormData;
39507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
39517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
39527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Process the status info first.
39537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
39547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BrowserStatusProcess();
39554d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong  if (gFormData->BrowserStatus != BROWSER_SUCCESS) {
39567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
39574d4deaaccb9b39106775d260ea0397c1991b0f04Eric Dong    // gFormData->BrowserStatus != BROWSER_SUCCESS, means only need to print the error info, return here.
39587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
39597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return EFI_SUCCESS;
39607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
39617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
39627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Status = DisplayPageFrame (FormData, &gStatementDimensions);
39637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (EFI_ERROR (Status)) {
39647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return Status;
39657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
39667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
39675a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  //
3968c4866c7710c250b83018de6a1fcde6433f87ff3eSamer El-Haj-Mahmoud elhaj <Samer El-Haj-Mahmoud  // Global Widths should be initialized before any MenuOption creation
3969c4866c7710c250b83018de6a1fcde6433f87ff3eSamer El-Haj-Mahmoud elhaj <Samer El-Haj-Mahmoud  // or the GetWidth() used in UiAddMenuOption() will return incorrect value.
3970c4866c7710c250b83018de6a1fcde6433f87ff3eSamer El-Haj-Mahmoud elhaj <Samer El-Haj-Mahmoud  //
3971c4866c7710c250b83018de6a1fcde6433f87ff3eSamer El-Haj-Mahmoud elhaj <Samer El-Haj-Mahmoud  //
3972c4866c7710c250b83018de6a1fcde6433f87ff3eSamer El-Haj-Mahmoud elhaj <Samer El-Haj-Mahmoud  //  Left                                              right
3973c4866c7710c250b83018de6a1fcde6433f87ff3eSamer El-Haj-Mahmoud elhaj <Samer El-Haj-Mahmoud  //   |<-.->|<-.........->|<- .........->|<-...........->|
3974c4866c7710c250b83018de6a1fcde6433f87ff3eSamer El-Haj-Mahmoud elhaj <Samer El-Haj-Mahmoud  //     Skip    Prompt         Option         Help
3975c4866c7710c250b83018de6a1fcde6433f87ff3eSamer El-Haj-Mahmoud elhaj <Samer El-Haj-Mahmoud  //
3976c4866c7710c250b83018de6a1fcde6433f87ff3eSamer El-Haj-Mahmoud elhaj <Samer El-Haj-Mahmoud  gOptionBlockWidth = (CHAR16) ((gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 3) + 1;
3977c4866c7710c250b83018de6a1fcde6433f87ff3eSamer El-Haj-Mahmoud elhaj <Samer El-Haj-Mahmoud  gHelpBlockWidth   = (CHAR16) (gOptionBlockWidth - 1 - LEFT_SKIPPED_COLUMNS);
3978c4866c7710c250b83018de6a1fcde6433f87ff3eSamer El-Haj-Mahmoud elhaj <Samer El-Haj-Mahmoud  gPromptBlockWidth = (CHAR16) (gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * (gOptionBlockWidth - 1) - 1);
3979c4866c7710c250b83018de6a1fcde6433f87ff3eSamer El-Haj-Mahmoud elhaj <Samer El-Haj-Mahmoud
3980c4866c7710c250b83018de6a1fcde6433f87ff3eSamer El-Haj-Mahmoud elhaj <Samer El-Haj-Mahmoud  ConvertStatementToMenu();
3981c4866c7710c250b83018de6a1fcde6433f87ff3eSamer El-Haj-Mahmoud elhaj <Samer El-Haj-Mahmoud
3982c4866c7710c250b83018de6a1fcde6433f87ff3eSamer El-Haj-Mahmoud elhaj <Samer El-Haj-Mahmoud  //
39835a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  // Check whether layout is changed.
39845a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  //
39855a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  if (mIsFirstForm
39865a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong      || (gOldFormEntry.HiiHandle != FormData->HiiHandle)
39875a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong      || (!CompareGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid))
39885a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong      || (gOldFormEntry.FormId != FormData->FormId)) {
39897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    mStatementLayoutIsChanged = TRUE;
39905a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  } else {
39915a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong    mStatementLayoutIsChanged = FALSE;
39927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
39937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
39947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Status = UiDisplayMenu(FormData);
39955a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong
39965a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  //
39975a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  // Backup last form info.
39985a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  //
39995a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  mIsFirstForm            = FALSE;
40005a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  gOldFormEntry.HiiHandle = FormData->HiiHandle;
40015a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  CopyGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid);
40025a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  gOldFormEntry.FormId    = FormData->FormId;
40037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
40047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return Status;
40057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
40067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
40077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
40085a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  Clear Screen to the initial state.
40095a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong**/
40105a9f73bf065eda6b830445dc907e778f4a13d8d7Eric DongVOID
40115a9f73bf065eda6b830445dc907e778f4a13d8d7Eric DongEFIAPI
40125a9f73bf065eda6b830445dc907e778f4a13d8d7Eric DongDriverClearDisplayPage (
40135a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  VOID
40145a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  )
40155a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong{
40165a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  ClearDisplayPage ();
40175a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  mIsFirstForm = TRUE;
40185a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong}
40195a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong
40205a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong/**
40215a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  Set Buffer to Value for Size bytes.
40225a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong
40235a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  @param  Buffer                 Memory to set.
40245a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  @param  Size                   Number of bytes to set
40255a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  @param  Value                  Value of the set operation.
40265a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong
40275a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong**/
40285a9f73bf065eda6b830445dc907e778f4a13d8d7Eric DongVOID
40295a9f73bf065eda6b830445dc907e778f4a13d8d7Eric DongSetUnicodeMem (
40305a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  IN VOID   *Buffer,
40315a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  IN UINTN  Size,
40325a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  IN CHAR16 Value
40335a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  )
40345a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong{
40355a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  CHAR16  *Ptr;
40365a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong
40375a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  Ptr = Buffer;
40385a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  while ((Size--)  != 0) {
40395a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong    *(Ptr++) = Value;
40405a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  }
40415a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong}
40425a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong
40435a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong/**
40447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Initialize Setup Browser driver.
40457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
40467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param ImageHandle     The image handle.
40477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param SystemTable     The system table.
40487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
40497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval EFI_SUCCESS    The Setup Browser module is initialized correctly..
40507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @return Other value if failed to initialize the Setup Browser module.
40517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
40527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
40537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFI_STATUS
40547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFIAPI
40557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongInitializeDisplayEngine (
40567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN EFI_HANDLE           ImageHandle,
40577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN EFI_SYSTEM_TABLE     *SystemTable
40587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
40597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
40607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_STATUS                          Status;
40617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_INPUT_KEY                       HotKey;
40627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_STRING                          NewString;
40637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL *FormBrowserEx2;
40647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
40657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
40667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Publish our HII data
40677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
40687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gHiiHandle = HiiAddPackages (
40697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                 &gDisplayEngineGuid,
40707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                 ImageHandle,
40717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                 DisplayEngineStrings,
40727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                 NULL
40737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                 );
40747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT (gHiiHandle != NULL);
40757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
40767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
40777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Install Form Display protocol
40787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
40797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Status = gBS->InstallProtocolInterface (
40807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  &mPrivateData.Handle,
40817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  &gEdkiiFormDisplayEngineProtocolGuid,
40827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  EFI_NATIVE_INTERFACE,
40837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  &mPrivateData.FromDisplayProt
40847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                  );
40857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT_EFI_ERROR (Status);
40867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
40877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  InitializeDisplayStrings();
40885a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong
40895a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  ZeroMem (&gHighligthMenuInfo, sizeof (gHighligthMenuInfo));
40905a9f73bf065eda6b830445dc907e778f4a13d8d7Eric Dong  ZeroMem (&gOldFormEntry, sizeof (gOldFormEntry));
40917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
40927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
40937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Use BrowserEx2 protocol to register HotKey.
40947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
40957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Status = gBS->LocateProtocol (&gEdkiiFormBrowserEx2ProtocolGuid, NULL, (VOID **) &FormBrowserEx2);
40967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (!EFI_ERROR (Status)) {
40977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
40987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Register the default HotKey F9 and F10 again.
40997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
41007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    HotKey.UnicodeChar = CHAR_NULL;
41017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    HotKey.ScanCode   = SCAN_F10;
41027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    NewString         = HiiGetString (gHiiHandle, STRING_TOKEN (FUNCTION_TEN_STRING), NULL);
41037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ASSERT (NewString != NULL);
41047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    FormBrowserEx2->RegisterHotKey (&HotKey, BROWSER_ACTION_SUBMIT, 0, NewString);
41057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
41067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    HotKey.ScanCode   = SCAN_F9;
41077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    NewString         = HiiGetString (gHiiHandle, STRING_TOKEN (FUNCTION_NINE_STRING), NULL);
41087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ASSERT (NewString != NULL);
41097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    FormBrowserEx2->RegisterHotKey (&HotKey, BROWSER_ACTION_DEFAULT, EFI_HII_DEFAULT_CLASS_STANDARD, NewString);
41107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
41117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
41127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return EFI_SUCCESS;
41137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
41147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
41157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
41167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  This is the default unload handle for display core drivers.
41177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
41187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param[in]  ImageHandle       The drivers' driver image.
41197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
41207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval EFI_SUCCESS           The image is unloaded.
41217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval Others                Failed to unload the image.
41227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
41237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
41247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFI_STATUS
41257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFIAPI
41267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUnloadDisplayEngine (
41277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN EFI_HANDLE             ImageHandle
41287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
41297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
41307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  HiiRemovePackages(gHiiHandle);
41317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
41327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreeDisplayStrings ();
41337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
413442645c3dcf0488c616422dcdfd1596939223f432Eric Dong  if (gHighligthMenuInfo.HLTOpCode != NULL) {
413542645c3dcf0488c616422dcdfd1596939223f432Eric Dong    FreePool (gHighligthMenuInfo.HLTOpCode);
413642645c3dcf0488c616422dcdfd1596939223f432Eric Dong  }
413742645c3dcf0488c616422dcdfd1596939223f432Eric Dong
413842645c3dcf0488c616422dcdfd1596939223f432Eric Dong  if (gHighligthMenuInfo.TOSOpCode != NULL) {
413942645c3dcf0488c616422dcdfd1596939223f432Eric Dong    FreePool (gHighligthMenuInfo.TOSOpCode);
4140336c8e116b3e2e11dccdac163d0a85fc3c58fd3dEric Dong  }
4141336c8e116b3e2e11dccdac163d0a85fc3c58fd3dEric Dong
41427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return EFI_SUCCESS;
41437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
4144