From 7c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1 Mon Sep 17 00:00:00 2001 From: Eric Dong Date: Mon, 12 Aug 2013 02:19:56 +0000 Subject: Update Browser to provide the customization possibilities. Signed-off-by: Eric Dong Reviewed-by: Liming Gao Tested-by: Laszlo Ersek git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14540 6f19259b-4bc3-4df7-8a09-765794883524 --- .../CustomizedDisplayLib/CustomizedDisplayLib.c | 936 +++++++++++++++++++++ 1 file changed, 936 insertions(+) create mode 100644 MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c (limited to 'MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c') diff --git a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c new file mode 100644 index 0000000000..84df7cc249 --- /dev/null +++ b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c @@ -0,0 +1,936 @@ +/** @file + + This library class defines a set of interfaces to customize Display module + +Copyright (c) 2013, Intel Corporation. All rights reserved.
+This program and the accompanying materials are licensed and made available under +the terms and conditions of the BSD License that accompanies this distribution. +The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php. + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ +#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 +UINT16 gLastClassOfVfr = 0; +BANNER_DATA *gBannerData; + +UINTN gFooterHeight; + +/** ++------------------------------------------------------------------------------+ +| Setup Page | ++------------------------------------------------------------------------------+ + +Statement +Statement +Statement + + + + + ++------------------------------------------------------------------------------+ +| F1=Scroll Help F9=Reset to Defaults F10=Save and Exit | +| ^"=Move Highlight Toggles Checkbox Esc=Discard Changes | ++------------------------------------------------------------------------------+ + StatusBar +**/ + +/** + This funtion 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 = ScreenDiemensionInfoValidate (FormData); + if (EFI_ERROR (Status)) { + return Status; + } + + gClassOfVfr = FORMSET_CLASS_PLATFORM_SETUP; + if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) { + gClassOfVfr = FORMSET_CLASS_MODEL_PAGE; + } + + ProcessExternedOpcode(FormData); + + // + // Calculate the ScreenForStatement. + // + ScreenForStatement->BottomRow = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight; + if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == 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 Last Vfr Class is same to current Vfr Class, + // they will have the same page frame. So, Page Frame is not required to be repainted. + // + if (gLastClassOfVfr == gClassOfVfr) { + UpdateStatusBar(NV_UPDATE_REQUIRED, FormData->SettingChangedFlag); + PrintFormTitle(FormData); + return EFI_SUCCESS; + } + + // + // Record last ClassOfVfr and Streen Information. + // + gLastClassOfVfr = gClassOfVfr; + + // + // 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); + + if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) { + return EFI_SUCCESS; + } + + if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) { + PrintBannerInfo (FormData); + } + + PrintFramework (); + + UpdateStatusBar(NV_UPDATE_REQUIRED, FormData->SettingChangedFlag); + + PrintFormTitle(FormData); + + 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 LeftColumnOfHelp; + UINTN RightColumnOfHelp; + UINTN TopRowOfHelp; + UINTN BottomRowOfHelp; + UINTN StartColumnOfHelp; + EFI_IFR_NUMERIC *NumericOp; + EFI_IFR_DATE *DateOp; + EFI_IFR_TIME *TimeOp; + BOOLEAN HexDisplay; + + 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; + + StartColumnOfHelp = gScreenDimensions.LeftColumn + 2; + LeftColumnOfHelp = gScreenDimensions.LeftColumn + 1; + RightColumnOfHelp = gScreenDimensions.RightColumn - 2; + TopRowOfHelp = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1; + BottomRowOfHelp = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 2; + + ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND); + if (Statement == NULL) { + // + // Print Key for Form without showable statement. + // + PrintHotKeyHelpString (FormData); + PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString); + 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); + + if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) { + PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString); + } + + if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP) || + (Statement->OpCode->OpCode == EFI_IFR_TIME_OP)) { + PrintAt ( + 0, + StartColumnOfHelp, + BottomRowOfHelp, + L"%c%c%c%c%s", + ARROW_UP, + ARROW_DOWN, + ARROW_RIGHT, + ARROW_LEFT, + gMoveHighlight + ); + PrintStringAt (SecCol, BottomRowOfHelp, gEnterString); + PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gAdjustNumber); + } else { + PrintAt (0, 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) { + PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gAdjustNumber); + } + PrintStringAt (SecCol, BottomRowOfHelp, gEnterString); + } + } else { + PrintStringAt (SecCol, BottomRowOfHelp, gEnterCommitString); + + // + // 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)) { + PrintStringAt ( + SecCol, + TopRowOfHelp, + HexDisplay ? gHexNumericInput : gDecNumericInput + ); + } else if (Statement->OpCode->OpCode != EFI_IFR_ORDERED_LIST_OP) { + PrintAt (0, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight); + } + + if (Statement->OpCode->OpCode == EFI_IFR_ORDERED_LIST_OP) { + PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gPlusString); + PrintStringAt (ThdCol, TopRowOfHelp, gMinusString); + } + + PrintStringAt (ThdCol, BottomRowOfHelp, gEnterEscapeString); + } + break; + + case EFI_IFR_CHECKBOX_OP: + PrintHotKeyHelpString (FormData); + + if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) { + PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString); + } + + PrintAt (0, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight); + PrintStringAt (SecCol, BottomRowOfHelp, gToggleCheckBox); + 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); + + if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) { + PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString); + } + + PrintAt (0, 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) { + PrintStringAt (SecCol, BottomRowOfHelp, gEnterString); + } + } else { + if (Statement->OpCode->OpCode != EFI_IFR_REF_OP) { + PrintStringAt ( + (gScreenDimensions.RightColumn - LibGetStringWidth (gEnterCommitString) / 2) / 2, + BottomRowOfHelp, + gEnterCommitString + ); + PrintStringAt (ThdCol, BottomRowOfHelp, gEnterEscapeString); + } + } + 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; + + // + // 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; + 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, TRUE); +} + +/** + 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) == 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 chracter 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); + gLastClassOfVfr = 0; +} + +/** + 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; +} + -- cgit v1.2.3