| /** @file | |
| This library class defines a set of interfaces to customize Display module | |
| Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR> | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| #include "CustomizedDisplayLibInternal.h" | |
| EFI_GUID gCustomizedDisplayLibGuid = { | |
| 0x99fdc8fd, 0x849b, 0x4eba, { 0xad, 0x13, 0xfb, 0x96, 0x99, 0xc9, 0xa, 0x4d } | |
| }; | |
| EFI_HII_HANDLE mCDLStringPackHandle; | |
| UINT16 gClassOfVfr; // Formset class information | |
| BOOLEAN gLibIsFirstForm = TRUE; | |
| BANNER_DATA *gBannerData; | |
| UINTN gFooterHeight; | |
| /** | |
| +------------------------------------------------------------------------------+ | |
| | Setup Page | | |
| +------------------------------------------------------------------------------+ | |
| Statement | |
| Statement | |
| Statement | |
| +------------------------------------------------------------------------------+ | |
| | F9=Reset to Defaults F10=Save | | |
| | ^"=Move Highlight <Spacebar> Toggles Checkbox Esc=Exit | | |
| +------------------------------------------------------------------------------+ | |
| StatusBar | |
| **/ | |
| /** | |
| This function defines Page Frame and Backgroud. | |
| Based on the above layout, it will be responsible for HeaderHeight, FooterHeight, | |
| StatusBarHeight and Backgroud. And, it will reserve Screen for Statement. | |
| @param[in] FormData Form Data to be shown in Page. | |
| @param[out] ScreenForStatement Screen to be used for Statement. (Prompt, Value and Help) | |
| @return Status | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| DisplayPageFrame ( | |
| IN FORM_DISPLAY_ENGINE_FORM *FormData, | |
| OUT EFI_SCREEN_DESCRIPTOR *ScreenForStatement | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| ASSERT (FormData != NULL && ScreenForStatement != NULL); | |
| if ((FormData == NULL) || (ScreenForStatement == NULL)) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| Status = ScreenDimensionInfoValidate (FormData); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| gClassOfVfr = FORMSET_CLASS_PLATFORM_SETUP; | |
| ProcessExternedOpcode (FormData); | |
| // | |
| // Calculate the ScreenForStatement. | |
| // | |
| ScreenForStatement->BottomRow = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight; | |
| if (gClassOfVfr == FORMSET_CLASS_FRONT_PAGE) { | |
| ScreenForStatement->TopRow = gScreenDimensions.TopRow + FRONT_PAGE_HEADER_HEIGHT; | |
| } else { | |
| ScreenForStatement->TopRow = gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT; | |
| } | |
| ScreenForStatement->LeftColumn = gScreenDimensions.LeftColumn; | |
| ScreenForStatement->RightColumn = gScreenDimensions.RightColumn; | |
| if ((gLibIsFirstForm) || ((FormData->Attribute & HII_DISPLAY_MODAL) != 0)) { | |
| // | |
| // Ensure we are in Text mode | |
| // | |
| gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); | |
| ClearLines (0, gScreenDimensions.RightColumn, 0, gScreenDimensions.BottomRow, KEYHELP_BACKGROUND); | |
| gLibIsFirstForm = FALSE; | |
| } | |
| // | |
| // Don't print frame for modal form. | |
| // | |
| if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) { | |
| return EFI_SUCCESS; | |
| } | |
| if (gClassOfVfr == FORMSET_CLASS_FRONT_PAGE) { | |
| PrintBannerInfo (FormData); | |
| } | |
| PrintFramework (FormData); | |
| UpdateStatusBar (NV_UPDATE_REQUIRED, FormData->SettingChangedFlag); | |
| return EFI_SUCCESS; | |
| } | |
| /** | |
| This function updates customized key panel's help information. | |
| The library will prepare those Strings for the basic key, ESC, Enter, Up/Down/Left/Right, +/-. | |
| and arrange them in Footer panel. | |
| @param[in] FormData Form Data to be shown in Page. FormData has the highlighted statement. | |
| @param[in] Statement The statement current selected. | |
| @param[in] Selected Whether or not a tag be selected. TRUE means Enter has hit this question. | |
| **/ | |
| VOID | |
| EFIAPI | |
| RefreshKeyHelp ( | |
| IN FORM_DISPLAY_ENGINE_FORM *FormData, | |
| IN FORM_DISPLAY_ENGINE_STATEMENT *Statement, | |
| IN BOOLEAN Selected | |
| ) | |
| { | |
| UINTN SecCol; | |
| UINTN ThdCol; | |
| UINTN RightColumnOfHelp; | |
| UINTN TopRowOfHelp; | |
| UINTN BottomRowOfHelp; | |
| UINTN StartColumnOfHelp; | |
| EFI_IFR_NUMERIC *NumericOp; | |
| EFI_IFR_DATE *DateOp; | |
| EFI_IFR_TIME *TimeOp; | |
| BOOLEAN HexDisplay; | |
| UINTN ColumnWidth1; | |
| UINTN ColumnWidth2; | |
| UINTN ColumnWidth3; | |
| CHAR16 *ColumnStr1; | |
| CHAR16 *ColumnStr2; | |
| CHAR16 *ColumnStr3; | |
| ASSERT (FormData != NULL); | |
| if (FormData == NULL) { | |
| return; | |
| } | |
| gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND); | |
| if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) { | |
| return; | |
| } | |
| SecCol = gScreenDimensions.LeftColumn + (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3; | |
| ThdCol = gScreenDimensions.LeftColumn + (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3 * 2; | |
| // | |
| // + 2 means leave 1 space before the first hotkey info. | |
| // | |
| StartColumnOfHelp = gScreenDimensions.LeftColumn + 2; | |
| RightColumnOfHelp = gScreenDimensions.RightColumn - 1; | |
| TopRowOfHelp = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1; | |
| BottomRowOfHelp = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 2; | |
| ColumnWidth1 = SecCol - StartColumnOfHelp; | |
| ColumnWidth2 = ThdCol - SecCol; | |
| ColumnWidth3 = RightColumnOfHelp - ThdCol; | |
| ColumnStr1 = gLibEmptyString; | |
| ColumnStr2 = gLibEmptyString; | |
| ColumnStr3 = gLibEmptyString; | |
| // | |
| // Clean the space at gScreenDimensions.LeftColumn + 1. | |
| // | |
| PrintStringAtWithWidth (StartColumnOfHelp - 1, BottomRowOfHelp, gLibEmptyString, 1); | |
| PrintStringAtWithWidth (StartColumnOfHelp - 1, TopRowOfHelp, gLibEmptyString, 1); | |
| if (Statement == NULL) { | |
| // | |
| // Print Key for Form without showable statement. | |
| // | |
| PrintHotKeyHelpString (FormData, TRUE); | |
| PrintStringAtWithWidth (StartColumnOfHelp, BottomRowOfHelp, gLibEmptyString, ColumnWidth1); | |
| PrintStringAtWithWidth (SecCol, BottomRowOfHelp, gLibEmptyString, ColumnWidth2); | |
| PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, gLibEmptyString, ColumnWidth1); | |
| if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) { | |
| ColumnStr3 = gEscapeString; | |
| } | |
| PrintStringAtWithWidth (ThdCol, BottomRowOfHelp, ColumnStr3, ColumnWidth3); | |
| return; | |
| } | |
| HexDisplay = FALSE; | |
| NumericOp = NULL; | |
| DateOp = NULL; | |
| TimeOp = NULL; | |
| if (Statement->OpCode->OpCode == EFI_IFR_NUMERIC_OP) { | |
| NumericOp = (EFI_IFR_NUMERIC *)Statement->OpCode; | |
| HexDisplay = (NumericOp->Flags & EFI_IFR_DISPLAY_UINT_HEX) == EFI_IFR_DISPLAY_UINT_HEX; | |
| } else if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP) { | |
| DateOp = (EFI_IFR_DATE *)Statement->OpCode; | |
| HexDisplay = (DateOp->Flags & EFI_IFR_DISPLAY_UINT_HEX) == EFI_IFR_DISPLAY_UINT_HEX; | |
| } else if (Statement->OpCode->OpCode == EFI_IFR_TIME_OP) { | |
| TimeOp = (EFI_IFR_TIME *)Statement->OpCode; | |
| HexDisplay = (TimeOp->Flags & EFI_IFR_DISPLAY_UINT_HEX) == EFI_IFR_DISPLAY_UINT_HEX; | |
| } | |
| switch (Statement->OpCode->OpCode) { | |
| case EFI_IFR_ORDERED_LIST_OP: | |
| case EFI_IFR_ONE_OF_OP: | |
| case EFI_IFR_NUMERIC_OP: | |
| case EFI_IFR_TIME_OP: | |
| case EFI_IFR_DATE_OP: | |
| if (!Selected) { | |
| PrintHotKeyHelpString (FormData, TRUE); | |
| if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) { | |
| ColumnStr3 = gEscapeString; | |
| } | |
| PrintStringAtWithWidth (ThdCol, BottomRowOfHelp, ColumnStr3, ColumnWidth3); | |
| if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP) || | |
| (Statement->OpCode->OpCode == EFI_IFR_TIME_OP)) | |
| { | |
| PrintAt ( | |
| ColumnWidth1, | |
| StartColumnOfHelp, | |
| BottomRowOfHelp, | |
| L"%c%c%c%c%s", | |
| ARROW_UP, | |
| ARROW_DOWN, | |
| ARROW_RIGHT, | |
| ARROW_LEFT, | |
| gMoveHighlight | |
| ); | |
| PrintStringAtWithWidth (SecCol, BottomRowOfHelp, gEnterString, ColumnWidth2); | |
| PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, gAdjustNumber, ColumnWidth1); | |
| } else { | |
| PrintAt (ColumnWidth1, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight); | |
| if ((Statement->OpCode->OpCode == EFI_IFR_NUMERIC_OP) && (NumericOp != NULL) && (LibGetFieldFromNum (Statement->OpCode) != 0)) { | |
| ColumnStr1 = gAdjustNumber; | |
| } | |
| PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, ColumnStr1, ColumnWidth1); | |
| PrintStringAtWithWidth (SecCol, BottomRowOfHelp, gEnterString, ColumnWidth2); | |
| } | |
| } else { | |
| PrintHotKeyHelpString (FormData, FALSE); | |
| PrintStringAtWithWidth (SecCol, BottomRowOfHelp, gEnterCommitString, ColumnWidth2); | |
| // | |
| // If it is a selected numeric with manual input, display different message | |
| // | |
| if ((Statement->OpCode->OpCode == EFI_IFR_NUMERIC_OP) || | |
| (Statement->OpCode->OpCode == EFI_IFR_DATE_OP) || | |
| (Statement->OpCode->OpCode == EFI_IFR_TIME_OP)) | |
| { | |
| ColumnStr2 = HexDisplay ? gHexNumericInput : gDecNumericInput; | |
| PrintStringAtWithWidth (StartColumnOfHelp, BottomRowOfHelp, gLibEmptyString, ColumnWidth1); | |
| } else { | |
| PrintAt (ColumnWidth1, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight); | |
| } | |
| if (Statement->OpCode->OpCode == EFI_IFR_ORDERED_LIST_OP) { | |
| ColumnStr1 = gPlusString; | |
| ColumnStr3 = gMinusString; | |
| } | |
| PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, ColumnStr1, ColumnWidth1); | |
| PrintStringAtWithWidth (ThdCol, TopRowOfHelp, ColumnStr3, ColumnWidth3); | |
| PrintStringAtWithWidth (SecCol, TopRowOfHelp, ColumnStr2, ColumnWidth2); | |
| PrintStringAtWithWidth (ThdCol, BottomRowOfHelp, gEnterEscapeString, ColumnWidth3); | |
| } | |
| break; | |
| case EFI_IFR_CHECKBOX_OP: | |
| PrintHotKeyHelpString (FormData, TRUE); | |
| if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) { | |
| ColumnStr3 = gEscapeString; | |
| } | |
| PrintStringAtWithWidth (ThdCol, BottomRowOfHelp, ColumnStr3, ColumnWidth3); | |
| PrintAt (ColumnWidth1, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight); | |
| PrintStringAtWithWidth (SecCol, BottomRowOfHelp, gToggleCheckBox, ColumnWidth2); | |
| PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, gLibEmptyString, ColumnWidth1); | |
| break; | |
| case EFI_IFR_REF_OP: | |
| case EFI_IFR_PASSWORD_OP: | |
| case EFI_IFR_STRING_OP: | |
| case EFI_IFR_TEXT_OP: | |
| case EFI_IFR_ACTION_OP: | |
| case EFI_IFR_RESET_BUTTON_OP: | |
| case EFI_IFR_SUBTITLE_OP: | |
| if (!Selected) { | |
| PrintHotKeyHelpString (FormData, TRUE); | |
| if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) { | |
| ColumnStr3 = gEscapeString; | |
| } | |
| PrintStringAtWithWidth (ThdCol, BottomRowOfHelp, ColumnStr3, ColumnWidth3); | |
| PrintAt (ColumnWidth1, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight); | |
| if ((Statement->OpCode->OpCode != EFI_IFR_TEXT_OP) && (Statement->OpCode->OpCode != EFI_IFR_SUBTITLE_OP)) { | |
| ColumnStr2 = gEnterString; | |
| } | |
| PrintStringAtWithWidth (SecCol, BottomRowOfHelp, ColumnStr2, ColumnWidth2); | |
| PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, ColumnStr1, ColumnWidth1); | |
| } else { | |
| PrintHotKeyHelpString (FormData, FALSE); | |
| if (Statement->OpCode->OpCode != EFI_IFR_REF_OP) { | |
| ColumnStr2 = gEnterCommitString; | |
| ColumnStr3 = gEnterEscapeString; | |
| } | |
| PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, ColumnStr1, ColumnWidth1); | |
| PrintStringAtWithWidth (StartColumnOfHelp, BottomRowOfHelp, ColumnStr1, ColumnWidth1); | |
| PrintStringAtWithWidth (SecCol, BottomRowOfHelp, ColumnStr2, ColumnWidth2); | |
| PrintStringAtWithWidth (ThdCol, BottomRowOfHelp, ColumnStr3, ColumnWidth3); | |
| } | |
| break; | |
| default: | |
| break; | |
| } | |
| } | |
| /** | |
| Update status bar. | |
| This function updates the status bar on the bottom of menu screen. It just shows StatusBar. | |
| Original logic in this function should be splitted out. | |
| @param[in] MessageType The type of message to be shown. InputError or Configuration Changed. | |
| @param[in] State Show or Clear Message. | |
| **/ | |
| VOID | |
| EFIAPI | |
| UpdateStatusBar ( | |
| IN UINTN MessageType, | |
| IN BOOLEAN State | |
| ) | |
| { | |
| UINTN Index; | |
| CHAR16 OptionWidth; | |
| OptionWidth = (CHAR16)((gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3); | |
| switch (MessageType) { | |
| case INPUT_ERROR: | |
| if (State) { | |
| gST->ConOut->SetAttribute (gST->ConOut, ERROR_TEXT); | |
| PrintStringAt ( | |
| gScreenDimensions.LeftColumn + OptionWidth, | |
| gScreenDimensions.BottomRow - 1, | |
| gInputErrorMessage | |
| ); | |
| } else { | |
| gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_BACKGROUND); | |
| for (Index = 0; Index < (LibGetStringWidth (gInputErrorMessage) - 2) / 2; Index++) { | |
| PrintStringAt (gScreenDimensions.LeftColumn + OptionWidth + Index, gScreenDimensions.BottomRow - 1, L" "); | |
| } | |
| } | |
| break; | |
| case NV_UPDATE_REQUIRED: | |
| // | |
| // Global setting support. Show configuration change on every form. | |
| // | |
| if (State) { | |
| gST->ConOut->SetAttribute (gST->ConOut, INFO_TEXT); | |
| PrintStringAt ( | |
| gScreenDimensions.LeftColumn + OptionWidth * 2, | |
| gScreenDimensions.BottomRow - 1, | |
| gNvUpdateMessage | |
| ); | |
| } else { | |
| gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_BACKGROUND); | |
| for (Index = 0; Index < (LibGetStringWidth (gNvUpdateMessage) - 2) / 2; Index++) { | |
| PrintStringAt ( | |
| (gScreenDimensions.LeftColumn + OptionWidth * 2 + Index), | |
| gScreenDimensions.BottomRow - 1, | |
| L" " | |
| ); | |
| } | |
| } | |
| break; | |
| default: | |
| break; | |
| } | |
| } | |
| /** | |
| Create popup window. It will replace CreateDialog(). | |
| This function draws OEM/Vendor specific pop up windows. | |
| @param[out] Key User Input Key | |
| @param ... String to be shown in Popup. The variable argument list is terminated by a NULL. | |
| **/ | |
| VOID | |
| EFIAPI | |
| CreateDialog ( | |
| OUT EFI_INPUT_KEY *Key OPTIONAL, | |
| ... | |
| ) | |
| { | |
| VA_LIST Marker; | |
| EFI_INPUT_KEY KeyValue; | |
| EFI_STATUS Status; | |
| UINTN LargestString; | |
| UINTN LineNum; | |
| UINTN Index; | |
| UINTN Count; | |
| CHAR16 Character; | |
| UINTN Start; | |
| UINTN End; | |
| UINTN Top; | |
| UINTN Bottom; | |
| CHAR16 *String; | |
| UINTN DimensionsWidth; | |
| UINTN DimensionsHeight; | |
| UINTN CurrentAttribute; | |
| BOOLEAN CursorVisible; | |
| // | |
| // If screen dimension info is not ready, get it from console. | |
| // | |
| if ((gScreenDimensions.RightColumn == 0) || (gScreenDimensions.BottomRow == 0)) { | |
| ZeroMem (&gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR)); | |
| gST->ConOut->QueryMode ( | |
| gST->ConOut, | |
| gST->ConOut->Mode->Mode, | |
| &gScreenDimensions.RightColumn, | |
| &gScreenDimensions.BottomRow | |
| ); | |
| } | |
| DimensionsWidth = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn; | |
| DimensionsHeight = gScreenDimensions.BottomRow - gScreenDimensions.TopRow; | |
| LargestString = 0; | |
| LineNum = 0; | |
| VA_START (Marker, Key); | |
| while ((String = VA_ARG (Marker, CHAR16 *)) != NULL) { | |
| LineNum++; | |
| if ((LibGetStringWidth (String) / 2) > LargestString) { | |
| LargestString = (LibGetStringWidth (String) / 2); | |
| } | |
| } | |
| VA_END (Marker); | |
| if ((LargestString + 2) > DimensionsWidth) { | |
| LargestString = DimensionsWidth - 2; | |
| } | |
| CurrentAttribute = gST->ConOut->Mode->Attribute; | |
| CursorVisible = gST->ConOut->Mode->CursorVisible; | |
| gST->ConOut->EnableCursor (gST->ConOut, FALSE); | |
| gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ()); | |
| // | |
| // Subtract the PopUp width from total Columns, allow for one space extra on | |
| // each end plus a border. | |
| // | |
| Start = (DimensionsWidth - LargestString - 2) / 2 + gScreenDimensions.LeftColumn + 1; | |
| End = Start + LargestString + 1; | |
| Top = ((DimensionsHeight - LineNum - 2) / 2) + gScreenDimensions.TopRow - 1; | |
| Bottom = Top + LineNum + 2; | |
| Character = BOXDRAW_DOWN_RIGHT; | |
| PrintCharAt (Start, Top, Character); | |
| Character = BOXDRAW_HORIZONTAL; | |
| for (Index = Start; Index + 2 < End; Index++) { | |
| PrintCharAt ((UINTN)-1, (UINTN)-1, Character); | |
| } | |
| Character = BOXDRAW_DOWN_LEFT; | |
| PrintCharAt ((UINTN)-1, (UINTN)-1, Character); | |
| Character = BOXDRAW_VERTICAL; | |
| Count = 0; | |
| VA_START (Marker, Key); | |
| for (Index = Top; Index + 2 < Bottom; Index++, Count++) { | |
| String = VA_ARG (Marker, CHAR16 *); | |
| if (String[0] == CHAR_NULL) { | |
| // | |
| // Passing in a NULL results in a blank space | |
| // | |
| ClearLines (Start, End, Index + 1, Index + 1, GetPopupColor ()); | |
| } else if (String[0] == L' ') { | |
| // | |
| // Passing in a space results in the assumption that this is where typing will occur | |
| // | |
| ClearLines (Start + 1, End - 1, Index + 1, Index + 1, POPUP_INVERSE_TEXT | POPUP_INVERSE_BACKGROUND); | |
| PrintStringAt ( | |
| ((DimensionsWidth - LibGetStringWidth (String) / 2) / 2) + gScreenDimensions.LeftColumn + 1, | |
| Index + 1, | |
| String + 1 | |
| ); | |
| } else { | |
| // | |
| // This will clear the background of the line - we never know who might have been | |
| // here before us. This differs from the next clear in that it used the non-reverse | |
| // video for normal printing. | |
| // | |
| ClearLines (Start, End, Index + 1, Index + 1, GetPopupColor ()); | |
| PrintStringAt ( | |
| ((DimensionsWidth - LibGetStringWidth (String) / 2) / 2) + gScreenDimensions.LeftColumn + 1, | |
| Index + 1, | |
| String | |
| ); | |
| } | |
| gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ()); | |
| PrintCharAt (Start, Index + 1, Character); | |
| PrintCharAt (End - 1, Index + 1, Character); | |
| } | |
| VA_END (Marker); | |
| Character = BOXDRAW_UP_RIGHT; | |
| PrintCharAt (Start, Bottom - 1, Character); | |
| Character = BOXDRAW_HORIZONTAL; | |
| for (Index = Start; Index + 2 < End; Index++) { | |
| PrintCharAt ((UINTN)-1, (UINTN)-1, Character); | |
| } | |
| Character = BOXDRAW_UP_LEFT; | |
| PrintCharAt ((UINTN)-1, (UINTN)-1, Character); | |
| if (Key != NULL) { | |
| Status = WaitForKeyStroke (&KeyValue); | |
| ASSERT_EFI_ERROR (Status); | |
| CopyMem (Key, &KeyValue, sizeof (EFI_INPUT_KEY)); | |
| } | |
| gST->ConOut->SetAttribute (gST->ConOut, CurrentAttribute); | |
| gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); | |
| } | |
| /** | |
| Confirm how to handle the changed data. | |
| @return Action BROWSER_ACTION_SUBMIT, BROWSER_ACTION_DISCARD or other values. | |
| **/ | |
| UINTN | |
| EFIAPI | |
| ConfirmDataChange ( | |
| VOID | |
| ) | |
| { | |
| CHAR16 YesResponse; | |
| CHAR16 NoResponse; | |
| EFI_INPUT_KEY Key; | |
| gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); | |
| YesResponse = gYesResponse[0]; | |
| NoResponse = gNoResponse[0]; | |
| // | |
| // If NV flag is up, prompt user | |
| // | |
| do { | |
| CreateDialog (&Key, gLibEmptyString, gSaveChanges, gAreYouSure, gLibEmptyString, NULL); | |
| } while | |
| ( | |
| (Key.ScanCode != SCAN_ESC) && | |
| ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse | UPPER_LOWER_CASE_OFFSET)) && | |
| ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse | UPPER_LOWER_CASE_OFFSET)) | |
| ); | |
| if (Key.ScanCode == SCAN_ESC) { | |
| return BROWSER_ACTION_NONE; | |
| } else if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse | UPPER_LOWER_CASE_OFFSET)) { | |
| return BROWSER_ACTION_SUBMIT; | |
| } else { | |
| return BROWSER_ACTION_DISCARD; | |
| } | |
| } | |
| /** | |
| OEM specifies whether Setup exits Page by ESC key. | |
| This function customized the behavior that whether Setup exits Page so that | |
| system able to boot when configuration is not changed. | |
| @retval TRUE Exits FrontPage | |
| @retval FALSE Don't exit FrontPage. | |
| **/ | |
| BOOLEAN | |
| EFIAPI | |
| FormExitPolicy ( | |
| VOID | |
| ) | |
| { | |
| return gClassOfVfr == FORMSET_CLASS_FRONT_PAGE ? FALSE : TRUE; | |
| } | |
| /** | |
| Set Timeout value for a ceratain Form to get user response. | |
| This function allows to set timeout value on a ceratain form if necessary. | |
| If timeout is not zero, the form will exit if user has no response in timeout. | |
| @param[in] FormData Form Data to be shown in Page | |
| @return 0 No timeout for this form. | |
| @return > 0 Timeout value in 100 ns units. | |
| **/ | |
| UINT64 | |
| EFIAPI | |
| FormExitTimeout ( | |
| IN FORM_DISPLAY_ENGINE_FORM *FormData | |
| ) | |
| { | |
| return 0; | |
| } | |
| // | |
| // Print Functions | |
| // | |
| /** | |
| Prints a unicode string to the default console, at | |
| the supplied cursor position, using L"%s" format. | |
| @param Column The cursor position to print the string at. When it is -1, use current Position. | |
| @param Row The cursor position to print the string at. When it is -1, use current Position. | |
| @param String String pointer. | |
| @return Length of string printed to the console | |
| **/ | |
| UINTN | |
| EFIAPI | |
| PrintStringAt ( | |
| IN UINTN Column, | |
| IN UINTN Row, | |
| IN CHAR16 *String | |
| ) | |
| { | |
| return PrintAt (0, Column, Row, L"%s", String); | |
| } | |
| /** | |
| Prints a unicode string to the default console, at | |
| the supplied cursor position, using L"%s" format. | |
| @param Column The cursor position to print the string at. When it is -1, use current Position. | |
| @param Row The cursor position to print the string at. When it is -1, use current Position. | |
| @param String String pointer. | |
| @param Width Width for String. | |
| @return Length of string printed to the console | |
| **/ | |
| UINTN | |
| EFIAPI | |
| PrintStringAtWithWidth ( | |
| IN UINTN Column, | |
| IN UINTN Row, | |
| IN CHAR16 *String, | |
| IN UINTN Width | |
| ) | |
| { | |
| return PrintAt (Width, Column, Row, L"%s", String); | |
| } | |
| /** | |
| Prints a character to the default console, at | |
| the supplied cursor position, using L"%c" format. | |
| @param Column The cursor position to print the string at. When it is -1, use current Position. | |
| @param Row The cursor position to print the string at. When it is -1, use current Position. | |
| @param Character Character to print. | |
| @return Length of string printed to the console. | |
| **/ | |
| UINTN | |
| EFIAPI | |
| PrintCharAt ( | |
| IN UINTN Column, | |
| IN UINTN Row, | |
| CHAR16 Character | |
| ) | |
| { | |
| return PrintAt (0, Column, Row, L"%c", Character); | |
| } | |
| /** | |
| Clear retangle with specified text attribute. | |
| @param LeftColumn Left column of retangle. | |
| @param RightColumn Right column of retangle. | |
| @param TopRow Start row of retangle. | |
| @param BottomRow End row of retangle. | |
| @param TextAttribute The character foreground and background. | |
| **/ | |
| VOID | |
| EFIAPI | |
| ClearLines ( | |
| IN UINTN LeftColumn, | |
| IN UINTN RightColumn, | |
| IN UINTN TopRow, | |
| IN UINTN BottomRow, | |
| IN UINTN TextAttribute | |
| ) | |
| { | |
| CHAR16 *Buffer; | |
| UINTN Row; | |
| // | |
| // For now, allocate an arbitrarily long buffer | |
| // | |
| Buffer = AllocateZeroPool (0x10000); | |
| ASSERT (Buffer != NULL); | |
| // | |
| // Set foreground and background as defined | |
| // | |
| gST->ConOut->SetAttribute (gST->ConOut, TextAttribute); | |
| // | |
| // Much faster to buffer the long string instead of print it a character at a time | |
| // | |
| LibSetUnicodeMem (Buffer, RightColumn - LeftColumn, L' '); | |
| // | |
| // Clear the desired area with the appropriate foreground/background | |
| // | |
| for (Row = TopRow; Row <= BottomRow; Row++) { | |
| PrintStringAt (LeftColumn, Row, Buffer); | |
| } | |
| gST->ConOut->SetCursorPosition (gST->ConOut, LeftColumn, TopRow); | |
| FreePool (Buffer); | |
| } | |
| // | |
| // Color Setting Functions | |
| // | |
| /** | |
| Get OEM/Vendor specific popup attribute colors. | |
| @retval Byte code color setting for popup color. | |
| **/ | |
| UINT8 | |
| EFIAPI | |
| GetPopupColor ( | |
| VOID | |
| ) | |
| { | |
| return POPUP_TEXT | POPUP_BACKGROUND; | |
| } | |
| /** | |
| Get OEM/Vendor specific popup attribute colors. | |
| @retval Byte code color setting for popup inverse color. | |
| **/ | |
| UINT8 | |
| EFIAPI | |
| GetPopupInverseColor ( | |
| VOID | |
| ) | |
| { | |
| return POPUP_INVERSE_TEXT | POPUP_INVERSE_BACKGROUND; | |
| } | |
| /** | |
| Get OEM/Vendor specific PickList color attribute. | |
| @retval Byte code color setting for pick list color. | |
| **/ | |
| UINT8 | |
| EFIAPI | |
| GetPickListColor ( | |
| VOID | |
| ) | |
| { | |
| return PICKLIST_HIGHLIGHT_TEXT | PICKLIST_HIGHLIGHT_BACKGROUND; | |
| } | |
| /** | |
| Get OEM/Vendor specific arrow color attribute. | |
| @retval Byte code color setting for arrow color. | |
| **/ | |
| UINT8 | |
| EFIAPI | |
| GetArrowColor ( | |
| VOID | |
| ) | |
| { | |
| return ARROW_TEXT | ARROW_BACKGROUND; | |
| } | |
| /** | |
| Get OEM/Vendor specific info text color attribute. | |
| @retval Byte code color setting for info text color. | |
| **/ | |
| UINT8 | |
| EFIAPI | |
| GetInfoTextColor ( | |
| VOID | |
| ) | |
| { | |
| return INFO_TEXT | FIELD_BACKGROUND; | |
| } | |
| /** | |
| Get OEM/Vendor specific help text color attribute. | |
| @retval Byte code color setting for help text color. | |
| **/ | |
| UINT8 | |
| EFIAPI | |
| GetHelpTextColor ( | |
| VOID | |
| ) | |
| { | |
| return HELP_TEXT | FIELD_BACKGROUND; | |
| } | |
| /** | |
| Get OEM/Vendor specific grayed out text color attribute. | |
| @retval Byte code color setting for grayed out text color. | |
| **/ | |
| UINT8 | |
| EFIAPI | |
| GetGrayedTextColor ( | |
| VOID | |
| ) | |
| { | |
| return FIELD_TEXT_GRAYED | FIELD_BACKGROUND; | |
| } | |
| /** | |
| Get OEM/Vendor specific highlighted text color attribute. | |
| @retval Byte code color setting for highlight text color. | |
| **/ | |
| UINT8 | |
| EFIAPI | |
| GetHighlightTextColor ( | |
| VOID | |
| ) | |
| { | |
| return PcdGet8 (PcdBrowserFieldTextHighlightColor) | PcdGet8 (PcdBrowserFieldBackgroundHighlightColor); | |
| } | |
| /** | |
| Get OEM/Vendor specific field text color attribute. | |
| @retval Byte code color setting for field text color. | |
| **/ | |
| UINT8 | |
| EFIAPI | |
| GetFieldTextColor ( | |
| VOID | |
| ) | |
| { | |
| return PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND; | |
| } | |
| /** | |
| Get OEM/Vendor specific subtitle text color attribute. | |
| @retval Byte code color setting for subtitle text color. | |
| **/ | |
| UINT8 | |
| EFIAPI | |
| GetSubTitleTextColor ( | |
| VOID | |
| ) | |
| { | |
| return PcdGet8 (PcdBrowserSubtitleTextColor) | FIELD_BACKGROUND; | |
| } | |
| /** | |
| Clear Screen to the initial state. | |
| **/ | |
| VOID | |
| EFIAPI | |
| ClearDisplayPage ( | |
| VOID | |
| ) | |
| { | |
| gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); | |
| gST->ConOut->ClearScreen (gST->ConOut); | |
| gLibIsFirstForm = TRUE; | |
| } | |
| /** | |
| Constructor of Customized Display Library Instance. | |
| @param ImageHandle The firmware allocated handle for the EFI image. | |
| @param SystemTable A pointer to the EFI System Table. | |
| @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| CustomizedDisplayLibConstructor ( | |
| IN EFI_HANDLE ImageHandle, | |
| IN EFI_SYSTEM_TABLE *SystemTable | |
| ) | |
| { | |
| mCDLStringPackHandle = HiiAddPackages (&gCustomizedDisplayLibGuid, ImageHandle, CustomizedDisplayLibStrings, NULL); | |
| ASSERT (mCDLStringPackHandle != NULL); | |
| InitializeLibStrings (); | |
| return EFI_SUCCESS; | |
| } | |
| /** | |
| Destructor of Customized Display Library Instance. | |
| @param ImageHandle The firmware allocated handle for the EFI image. | |
| @param SystemTable A pointer to the EFI System Table. | |
| @retval EFI_SUCCESS The destructor completed successfully. | |
| @retval Other value The destructor did not complete successfully. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| CustomizedDisplayLibDestructor ( | |
| IN EFI_HANDLE ImageHandle, | |
| IN EFI_SYSTEM_TABLE *SystemTable | |
| ) | |
| { | |
| HiiRemovePackages (mCDLStringPackHandle); | |
| FreeLibStrings (); | |
| return EFI_SUCCESS; | |
| } |