/** Show all registered HotKey help strings on bottom Rows. @param FormData The curent input form data info. @param SetState Set HotKey or Clear HotKey **/ VOID PrintHotKeyHelpString ( IN FORM_DISPLAY_ENGINE_FORM *FormData, IN BOOLEAN SetState ) { UINTN CurrentCol; UINTN CurrentRow; UINTN BottomRowOfHotKeyHelp; UINTN ColumnIndexWidth; UINTN ColumnWidth; UINTN ColumnIndex; UINTN Index; EFI_SCREEN_DESCRIPTOR LocalScreen; LIST_ENTRY *Link; BROWSER_HOT_KEY *HotKey; CHAR16 BakChar; CHAR16 *ColumnStr; CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR)); ColumnWidth = (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3; BottomRowOfHotKeyHelp = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 3; ColumnStr = gLibEmptyString; // // Calculate total number of Register HotKeys. // Index = 0; Link = GetFirstNode (&FormData->HotKeyListHead); while (!IsNull (&FormData->HotKeyListHead, Link)) { HotKey = BROWSER_HOT_KEY_FROM_LINK (Link); // // Calculate help information Column and Row. // ColumnIndex = Index % 3; if (ColumnIndex == 0) { CurrentCol = LocalScreen.LeftColumn + 2 * ColumnWidth; ColumnIndexWidth = ColumnWidth - 1; } else if (ColumnIndex == 1) { CurrentCol = LocalScreen.LeftColumn + ColumnWidth; ColumnIndexWidth = ColumnWidth; } else { CurrentCol = LocalScreen.LeftColumn + 2; ColumnIndexWidth = ColumnWidth - 2; } CurrentRow = BottomRowOfHotKeyHelp - Index / 3; // // Help string can't exceed ColumnWidth. One Row will show three Help information. // BakChar = L'\0'; if (StrLen (HotKey->HelpString) > ColumnIndexWidth) { BakChar = HotKey->HelpString[ColumnIndexWidth]; HotKey->HelpString[ColumnIndexWidth] = L'\0'; } // // Print HotKey help string on bottom Row. // if (SetState) { ColumnStr = HotKey->HelpString; } PrintStringAtWithWidth (CurrentCol, CurrentRow, ColumnStr, ColumnIndexWidth); if (BakChar != L'\0') { HotKey->HelpString[ColumnIndexWidth] = BakChar; } // // Get Next Hot Key. // Link = GetNextNode (&FormData->HotKeyListHead, Link); Index ++; } if (SetState) { // // Clear KeyHelp // CurrentRow = BottomRowOfHotKeyHelp - Index / 3; ColumnIndex = Index % 3; if (ColumnIndex == 0) { CurrentCol = LocalScreen.LeftColumn + 2 * ColumnWidth; ColumnIndexWidth = ColumnWidth - 1; ColumnIndex ++; PrintStringAtWithWidth (CurrentCol, CurrentRow, gLibEmptyString, ColumnIndexWidth); } if (ColumnIndex == 1) { CurrentCol = LocalScreen.LeftColumn + ColumnWidth; ColumnIndexWidth = ColumnWidth; PrintStringAtWithWidth (CurrentCol, CurrentRow, gLibEmptyString, ColumnIndexWidth); } } return; }
/** 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; } }
/** Print framework and form title for a page. @param[in] FormData Form Data to be shown in Page **/ VOID PrintFramework ( IN FORM_DISPLAY_ENGINE_FORM *FormData ) { UINTN Index; CHAR16 Character; CHAR16 *Buffer; UINTN Row; CHAR16 *TitleStr; UINTN TitleColumn; if (gClassOfVfr != FORMSET_CLASS_PLATFORM_SETUP) { // // Only Setup page needs Framework // ClearLines ( gScreenDimensions.LeftColumn, gScreenDimensions.RightColumn, gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight, gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 1, KEYHELP_TEXT | KEYHELP_BACKGROUND ); return; } Buffer = AllocateZeroPool (0x10000); ASSERT (Buffer != NULL); Character = BOXDRAW_HORIZONTAL; for (Index = 0; Index + 2 < (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn); Index++) { Buffer[Index] = Character; } // // Print Top border line // +------------------------------------------------------------------------------+ // ? ? // +------------------------------------------------------------------------------+ // gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | TITLE_BACKGROUND); Character = BOXDRAW_DOWN_RIGHT; PrintCharAt (gScreenDimensions.LeftColumn, gScreenDimensions.TopRow, Character); PrintStringAt ((UINTN) -1, (UINTN) -1, Buffer); Character = BOXDRAW_DOWN_LEFT; PrintCharAt ((UINTN) -1, (UINTN) -1, Character); Character = BOXDRAW_VERTICAL; for (Row = gScreenDimensions.TopRow + 1; Row <= gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 2; Row++) { PrintCharAt (gScreenDimensions.LeftColumn, Row, Character); PrintCharAt (gScreenDimensions.RightColumn - 1, Row, Character); } // // Print Form Title // TitleStr = LibGetToken (FormData->FormTitle, FormData->HiiHandle); ASSERT (TitleStr != NULL); TitleColumn = (gScreenDimensions.RightColumn + gScreenDimensions.LeftColumn - LibGetStringWidth (TitleStr) / 2) / 2; PrintStringAtWithWidth (gScreenDimensions.LeftColumn + 1, gScreenDimensions.TopRow + 1, gLibEmptyString, TitleColumn - gScreenDimensions.LeftColumn - 1); PrintStringAtWithWidth ( TitleColumn, gScreenDimensions.TopRow + 1, TitleStr, gScreenDimensions.RightColumn - 1 - TitleColumn ); FreePool (TitleStr); Character = BOXDRAW_UP_RIGHT; PrintCharAt (gScreenDimensions.LeftColumn, gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1, Character); PrintStringAt ((UINTN) -1, (UINTN) -1, Buffer); Character = BOXDRAW_UP_LEFT; PrintCharAt ((UINTN) -1, (UINTN) -1, Character); // // Print Bottom border line // +------------------------------------------------------------------------------+ // ? ? // +------------------------------------------------------------------------------+ // Character = BOXDRAW_DOWN_RIGHT; PrintCharAt (gScreenDimensions.LeftColumn, gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight, Character); PrintStringAt ((UINTN) -1, (UINTN) -1, Buffer); Character = BOXDRAW_DOWN_LEFT; PrintCharAt ((UINTN) -1, (UINTN) -1, Character); Character = BOXDRAW_VERTICAL; for (Row = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1; Row <= gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 2; Row++ ) { PrintCharAt (gScreenDimensions.LeftColumn, Row, Character); PrintCharAt (gScreenDimensions.RightColumn - 1, Row, Character); } Character = BOXDRAW_UP_RIGHT; PrintCharAt (gScreenDimensions.LeftColumn, gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 1, Character); PrintStringAt ((UINTN) -1, (UINTN) -1, Buffer); Character = BOXDRAW_UP_LEFT; PrintCharAt ((UINTN) -1, (UINTN) -1, Character); FreePool (Buffer); }