/** 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); }
/** 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); }
/** 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) { 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) { 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) { 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; } }