/** @file Copyright (C) 2020, vit9696. All rights reserved. All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which 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 #include #include #include #include #include #include #include #include #include /* * ISO Latin-1 Font * * Copyright (c) 2000 * Ka-Ping Yee * * This font may be freely used for any purpose. */ #define ISO_CHAR_MIN 0x21 #define ISO_CHAR_MAX 0x7E #define ISO_CHAR_WIDTH 8 #define ISO_CHAR_HEIGHT 16 STATIC UINT8 mIsoFontData[(ISO_CHAR_MAX - ISO_CHAR_MIN + 1)*(ISO_CHAR_HEIGHT - 2)] = { /* 33 */ 0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00, /* 34 */ 0x00,0x6c,0x6c,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 35 */ 0x00,0x00,0x36,0x36,0x7f,0x36,0x36,0x7f,0x36,0x36,0x00,0x00,0x00,0x00, /* 36 */ 0x08,0x08,0x3e,0x6b,0x0b,0x0b,0x3e,0x68,0x68,0x6b,0x3e,0x08,0x08,0x00, /* 37 */ 0x00,0x00,0x33,0x13,0x18,0x08,0x0c,0x04,0x06,0x32,0x33,0x00,0x00,0x00, /* 38 */ 0x00,0x1c,0x36,0x36,0x1c,0x6c,0x3e,0x33,0x33,0x7b,0xce,0x00,0x00,0x00, /* 39 */ 0x00,0x18,0x18,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40 */ 0x00,0x30,0x18,0x18,0x0c,0x0c,0x0c,0x0c,0x0c,0x18,0x18,0x30,0x00,0x00, /* 41 */ 0x00,0x0c,0x18,0x18,0x30,0x30,0x30,0x30,0x30,0x18,0x18,0x0c,0x00,0x00, /* 42 */ 0x00,0x00,0x00,0x00,0x36,0x1c,0x7f,0x1c,0x36,0x00,0x00,0x00,0x00,0x00, /* 43 */ 0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,0x00, /* 44 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x0c,0x00,0x00, /* 45 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 46 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00, /* 47 */ 0x00,0x60,0x20,0x30,0x10,0x18,0x08,0x0c,0x04,0x06,0x02,0x03,0x00,0x00, /* 48 */ 0x00,0x3e,0x63,0x63,0x63,0x6b,0x6b,0x63,0x63,0x63,0x3e,0x00,0x00,0x00, /* 49 */ 0x00,0x18,0x1e,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00, /* 50 */ 0x00,0x3e,0x63,0x60,0x60,0x30,0x18,0x0c,0x06,0x03,0x7f,0x00,0x00,0x00, /* 51 */ 0x00,0x3e,0x63,0x60,0x60,0x3c,0x60,0x60,0x60,0x63,0x3e,0x00,0x00,0x00, /* 52 */ 0x00,0x30,0x38,0x3c,0x36,0x33,0x7f,0x30,0x30,0x30,0x30,0x00,0x00,0x00, /* 53 */ 0x00,0x7f,0x03,0x03,0x3f,0x60,0x60,0x60,0x60,0x63,0x3e,0x00,0x00,0x00, /* 54 */ 0x00,0x3c,0x06,0x03,0x03,0x3f,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00, /* 55 */ 0x00,0x7f,0x60,0x30,0x30,0x18,0x18,0x18,0x0c,0x0c,0x0c,0x00,0x00,0x00, /* 56 */ 0x00,0x3e,0x63,0x63,0x63,0x3e,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00, /* 57 */ 0x00,0x3e,0x63,0x63,0x63,0x7e,0x60,0x60,0x60,0x30,0x1e,0x00,0x00,0x00, /* 58 */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00, /* 59 */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x0c,0x00,0x00, /* 60 */ 0x00,0x60,0x30,0x18,0x0c,0x06,0x06,0x0c,0x18,0x30,0x60,0x00,0x00,0x00, /* 61 */ 0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00, /* 62 */ 0x00,0x06,0x0c,0x18,0x30,0x60,0x60,0x30,0x18,0x0c,0x06,0x00,0x00,0x00, /* 63 */ 0x00,0x3e,0x63,0x60,0x30,0x30,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00, /* 64 */ 0x00,0x3c,0x66,0x73,0x7b,0x6b,0x6b,0x7b,0x33,0x06,0x3c,0x00,0x00,0x00, /* 65 */ 0x00,0x3e,0x63,0x63,0x63,0x7f,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00, /* 66 */ 0x00,0x3f,0x63,0x63,0x63,0x3f,0x63,0x63,0x63,0x63,0x3f,0x00,0x00,0x00, /* 67 */ 0x00,0x3c,0x66,0x03,0x03,0x03,0x03,0x03,0x03,0x66,0x3c,0x00,0x00,0x00, /* 68 */ 0x00,0x1f,0x33,0x63,0x63,0x63,0x63,0x63,0x63,0x33,0x1f,0x00,0x00,0x00, /* 69 */ 0x00,0x7f,0x03,0x03,0x03,0x3f,0x03,0x03,0x03,0x03,0x7f,0x00,0x00,0x00, /* 70 */ 0x00,0x7f,0x03,0x03,0x03,0x3f,0x03,0x03,0x03,0x03,0x03,0x00,0x00,0x00, /* 71 */ 0x00,0x3c,0x66,0x03,0x03,0x03,0x73,0x63,0x63,0x66,0x7c,0x00,0x00,0x00, /* 72 */ 0x00,0x63,0x63,0x63,0x63,0x7f,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00, /* 73 */ 0x00,0x3c,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00, /* 74 */ 0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x33,0x1e,0x00,0x00,0x00, /* 75 */ 0x00,0x63,0x33,0x1b,0x0f,0x07,0x07,0x0f,0x1b,0x33,0x63,0x00,0x00,0x00, /* 76 */ 0x00,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x7f,0x00,0x00,0x00, /* 77 */ 0x00,0x63,0x63,0x77,0x7f,0x7f,0x6b,0x6b,0x63,0x63,0x63,0x00,0x00,0x00, /* 78 */ 0x00,0x63,0x63,0x67,0x6f,0x6f,0x7b,0x7b,0x73,0x63,0x63,0x00,0x00,0x00, /* 79 */ 0x00,0x3e,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00, /* 80 */ 0x00,0x3f,0x63,0x63,0x63,0x63,0x3f,0x03,0x03,0x03,0x03,0x00,0x00,0x00, /* 81 */ 0x00,0x3e,0x63,0x63,0x63,0x63,0x63,0x63,0x6f,0x7b,0x3e,0x30,0x60,0x00, /* 82 */ 0x00,0x3f,0x63,0x63,0x63,0x63,0x3f,0x1b,0x33,0x63,0x63,0x00,0x00,0x00, /* 83 */ 0x00,0x3e,0x63,0x03,0x03,0x0e,0x38,0x60,0x60,0x63,0x3e,0x00,0x00,0x00, /* 84 */ 0x00,0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00, /* 85 */ 0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00, /* 86 */ 0x00,0x63,0x63,0x63,0x63,0x63,0x36,0x36,0x1c,0x1c,0x08,0x00,0x00,0x00, /* 87 */ 0x00,0x63,0x63,0x6b,0x6b,0x6b,0x6b,0x7f,0x36,0x36,0x36,0x00,0x00,0x00, /* 88 */ 0x00,0x63,0x63,0x36,0x36,0x1c,0x1c,0x36,0x36,0x63,0x63,0x00,0x00,0x00, /* 89 */ 0x00,0xc3,0xc3,0x66,0x66,0x3c,0x3c,0x18,0x18,0x18,0x18,0x00,0x00,0x00, /* 90 */ 0x00,0x7f,0x30,0x30,0x18,0x18,0x0c,0x0c,0x06,0x06,0x7f,0x00,0x00,0x00, /* 91 */ 0x00,0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3c,0x00,0x00,0x00, /* 92 */ 0x00,0x03,0x02,0x06,0x04,0x0c,0x08,0x18,0x10,0x30,0x20,0x60,0x00,0x00, /* 93 */ 0x00,0x3c,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3c,0x00,0x00,0x00, /* 94 */ 0x08,0x1c,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 95 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00, /* 96 */ 0x00,0x0c,0x0c,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 97 */ 0x00,0x00,0x00,0x00,0x3e,0x60,0x7e,0x63,0x63,0x73,0x6e,0x00,0x00,0x00, /* 98 */ 0x00,0x03,0x03,0x03,0x3b,0x67,0x63,0x63,0x63,0x67,0x3b,0x00,0x00,0x00, /* 99 */ 0x00,0x00,0x00,0x00,0x3e,0x63,0x03,0x03,0x03,0x63,0x3e,0x00,0x00,0x00, /* 100 */ 0x00,0x60,0x60,0x60,0x6e,0x73,0x63,0x63,0x63,0x73,0x6e,0x00,0x00,0x00, /* 101 */ 0x00,0x00,0x00,0x00,0x3e,0x63,0x63,0x7f,0x03,0x63,0x3e,0x00,0x00,0x00, /* 102 */ 0x00,0x3c,0x66,0x06,0x1f,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x00, /* 103 */ 0x00,0x00,0x00,0x00,0x6e,0x73,0x63,0x63,0x63,0x73,0x6e,0x60,0x63,0x3e, /* 104 */ 0x00,0x03,0x03,0x03,0x3b,0x67,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00, /* 105 */ 0x00,0x0c,0x0c,0x00,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x38,0x00,0x00,0x00, /* 106 */ 0x00,0x30,0x30,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x33,0x1e, /* 107 */ 0x00,0x03,0x03,0x03,0x63,0x33,0x1b,0x0f,0x1f,0x33,0x63,0x00,0x00,0x00, /* 108 */ 0x00,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x38,0x00,0x00,0x00, /* 109 */ 0x00,0x00,0x00,0x00,0x35,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x00,0x00,0x00, /* 110 */ 0x00,0x00,0x00,0x00,0x3b,0x67,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00, /* 111 */ 0x00,0x00,0x00,0x00,0x3e,0x63,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00, /* 112 */ 0x00,0x00,0x00,0x00,0x3b,0x67,0x63,0x63,0x63,0x67,0x3b,0x03,0x03,0x03, /* 113 */ 0x00,0x00,0x00,0x00,0x6e,0x73,0x63,0x63,0x63,0x73,0x6e,0x60,0xe0,0x60, /* 114 */ 0x00,0x00,0x00,0x00,0x3b,0x67,0x03,0x03,0x03,0x03,0x03,0x00,0x00,0x00, /* 115 */ 0x00,0x00,0x00,0x00,0x3e,0x63,0x0e,0x38,0x60,0x63,0x3e,0x00,0x00,0x00, /* 116 */ 0x00,0x00,0x0c,0x0c,0x3e,0x0c,0x0c,0x0c,0x0c,0x0c,0x38,0x00,0x00,0x00, /* 117 */ 0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x73,0x6e,0x00,0x00,0x00, /* 118 */ 0x00,0x00,0x00,0x00,0x63,0x63,0x36,0x36,0x1c,0x1c,0x08,0x00,0x00,0x00, /* 119 */ 0x00,0x00,0x00,0x00,0x63,0x6b,0x6b,0x6b,0x3e,0x36,0x36,0x00,0x00,0x00, /* 120 */ 0x00,0x00,0x00,0x00,0x63,0x36,0x1c,0x1c,0x1c,0x36,0x63,0x00,0x00,0x00, /* 121 */ 0x00,0x00,0x00,0x00,0x63,0x63,0x36,0x36,0x1c,0x1c,0x0c,0x0c,0x06,0x03, /* 122 */ 0x00,0x00,0x00,0x00,0x7f,0x60,0x30,0x18,0x0c,0x06,0x7f,0x00,0x00,0x00, /* 123 */ 0x00,0x70,0x18,0x18,0x18,0x18,0x0e,0x18,0x18,0x18,0x18,0x70,0x00,0x00, /* 124 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00, /* 125 */ 0x00,0x0e,0x18,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0e,0x00,0x00, /* 126 */ 0x00,0x00,0x00,0x00,0x00,0x6e,0x3b,0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; STATIC UINT32 mGraphicsEfiColors[16] = { 0x00000000, // BLACK 0x00000098, // LIGHTBLUE 0x00009800, // LIGHGREEN 0x00009898, // LIGHCYAN 0x00980000, // LIGHRED 0x00980098, // MAGENTA 0x00989800, // BROWN 0x00989898, // LIGHTGRAY 0x00303030, // DARKGRAY - BRIGHT BLACK 0x000000ff, // BLUE 0x0000ff00, // LIME 0x0000ffff, // CYAN 0x00ff0000, // RED 0x00ff00ff, // FUCHSIA 0x00ffff00, // YELLOW 0x00ffffff // WHITE }; STATIC EFI_GRAPHICS_OUTPUT_PROTOCOL *mGraphicsOutput; STATIC UINTN mConsoleWidth; STATIC UINTN mConsoleHeight; STATIC UINTN mConsoleMaxPosX; STATIC UINTN mConsoleMaxPosY; STATIC UINTN mCursorPosX; STATIC UINTN mCursorPosY; STATIC BOOLEAN mCursorOnscreen; STATIC UINT8 mFontScale; STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION mBackgroundColor; STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION mForegroundColor; STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION *mCharacterBuffer; #define TGT_CHAR_WIDTH ((UINTN)(ISO_CHAR_WIDTH) * mFontScale) #define TGT_CHAR_HEIGHT ((UINTN)(ISO_CHAR_HEIGHT) * mFontScale) #define TGT_CHAR_AREA ((TGT_CHAR_WIDTH) * (TGT_CHAR_HEIGHT)) /** Render character to TGT_CHAR_AREA buffer. @param[in] Char Character code. @param[in] FgColor Character colour. @param[in] BgColor Background colour. @param[out] Buffer Character buffer. **/ STATIC VOID RenderChar ( IN CHAR16 Char, OUT VOID *Buffer ) { UINT32 *DstBuffer; UINT8 *SrcBuffer; UINT32 Line; UINT32 Index; UINT32 Index2; UINT8 Mask; DstBuffer = Buffer; if ((Char >= 0 && Char < ISO_CHAR_MIN) || Char == 0x7F) { SetMem32 (DstBuffer, TGT_CHAR_AREA * sizeof (DstBuffer[0]), mBackgroundColor.Raw); return; } if (Char < ISO_CHAR_MIN || Char > ISO_CHAR_MAX) { Char = L'_'; } SrcBuffer = mIsoFontData + ((Char - ISO_CHAR_MIN) * (ISO_CHAR_HEIGHT - 2)); SetMem32 (DstBuffer, TGT_CHAR_WIDTH * mFontScale * sizeof (DstBuffer[0]), mBackgroundColor.Raw); DstBuffer += TGT_CHAR_WIDTH * mFontScale; for (Line = 0; Line < ISO_CHAR_HEIGHT - 2; ++Line) { // // Iterate, while the single bit drops to the right. // for (Index = 0; Index < mFontScale; ++Index) { Mask = 1; do { for (Index2 = 0; Index2 < mFontScale; ++Index2) { *DstBuffer = (*SrcBuffer & Mask) ? mForegroundColor.Raw : mBackgroundColor.Raw; ++DstBuffer; } Mask <<= 1U; } while (Mask != 0); } ++SrcBuffer; } SetMem32 (DstBuffer, TGT_CHAR_WIDTH * mFontScale * sizeof (DstBuffer[0]), mBackgroundColor.Raw); } STATIC VOID RenderCursor ( IN UINTN PosX, IN UINTN PosY, IN BOOLEAN Enabled ) { // // Disabled and invisible. // if (!Enabled && !mCursorOnscreen) { return; } // // Hide previous. // if (mCursorOnscreen) { mGraphicsOutput->Blt ( mGraphicsOutput, &mBackgroundColor.Pixel, EfiBltVideoFill, 0, 0, TGT_CHAR_WIDTH + mCursorPosX * TGT_CHAR_WIDTH + mFontScale, TGT_CHAR_HEIGHT + mCursorPosY * TGT_CHAR_HEIGHT - mFontScale + TGT_CHAR_HEIGHT, TGT_CHAR_WIDTH - mFontScale * 2, mFontScale, 0 ); mCursorOnscreen = FALSE; } // // Draw new. // if (Enabled) { mGraphicsOutput->Blt ( mGraphicsOutput, &mForegroundColor.Pixel, EfiBltVideoFill, 0, 0, TGT_CHAR_WIDTH + PosX * TGT_CHAR_WIDTH + mFontScale, TGT_CHAR_HEIGHT + PosY * TGT_CHAR_HEIGHT - mFontScale + TGT_CHAR_HEIGHT, TGT_CHAR_WIDTH - mFontScale * 2, mFontScale, 0 ); mCursorPosX = PosX; mCursorPosY = PosY; mCursorOnscreen = TRUE; } } STATIC EFI_STATUS EFIAPI AsciiTextReset ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN BOOLEAN ExtendedVerification ) { EFI_STATUS Status; EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; Status = gBS->HandleProtocol ( gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &mGraphicsOutput ); if (EFI_ERROR (Status)) { return EFI_DEVICE_ERROR; } Info = mGraphicsOutput->Mode->Info; if (Info->HorizontalResolution < TGT_CHAR_WIDTH * 3 || Info->VerticalResolution < TGT_CHAR_HEIGHT * 3 || (Info->PixelFormat != PixelRedGreenBlueReserved8BitPerColor && Info->PixelFormat != PixelBlueGreenRedReserved8BitPerColor)) { return EFI_DEVICE_ERROR; } if (mCharacterBuffer != NULL) { FreePool (mCharacterBuffer); } mCharacterBuffer = AllocatePool (TGT_CHAR_AREA * sizeof (mCharacterBuffer[0])); if (mCharacterBuffer == NULL) { return EFI_DEVICE_ERROR; } mConsoleWidth = (Info->HorizontalResolution / TGT_CHAR_WIDTH) - 2; mConsoleHeight = (Info->VerticalResolution / TGT_CHAR_HEIGHT) - 2; This->Mode->CursorColumn = 0; This->Mode->CursorRow = 0; mCursorOnscreen = FALSE; mCursorPosX = 0; mCursorPosY = 0; mConsoleMaxPosX = 0; mConsoleMaxPosY = 0; mBackgroundColor.Raw = mGraphicsEfiColors[0]; mForegroundColor.Raw = mGraphicsEfiColors[ARRAY_SIZE (mGraphicsEfiColors) - 1]; mGraphicsOutput->Blt ( mGraphicsOutput, &mBackgroundColor.Pixel, EfiBltVideoFill, 0, 0, 0, 0, Info->HorizontalResolution, Info->VerticalResolution, 0 ); return EFI_SUCCESS; } STATIC EFI_STATUS EFIAPI AsciiTextOutputString ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN CHAR16 *String ) { UINTN Index; for (Index = 0; String[Index] != '\0'; ++Index) { if (String[Index] == '\r') { This->Mode->CursorColumn = 0; continue; } if ((UINTN) This->Mode->CursorColumn >= mConsoleWidth || String[Index] == '\n') { if ((UINTN) This->Mode->CursorColumn >= mConsoleWidth) { This->Mode->CursorColumn = 0; } ++This->Mode->CursorRow; mConsoleMaxPosY = MAX (mConsoleMaxPosY, (UINTN) This->Mode->CursorRow); if (String[Index] == '\n') { continue; } } if ((UINTN) This->Mode->CursorRow >= mConsoleHeight) { // // TODO: Many GOP implementations (e.g. NVIDIA) fail to perform overlapping operations. // mGraphicsOutput->Blt ( mGraphicsOutput, NULL, EfiBltVideoToVideo, 0, TGT_CHAR_HEIGHT * 2, 0, TGT_CHAR_HEIGHT, mGraphicsOutput->Mode->Info->HorizontalResolution, TGT_CHAR_HEIGHT * (mConsoleHeight - 1), 0 ); mGraphicsOutput->Blt ( mGraphicsOutput, &mBackgroundColor.Pixel, EfiBltVideoFill, 0, 0, 0, TGT_CHAR_HEIGHT * mConsoleHeight, mGraphicsOutput->Mode->Info->HorizontalResolution, TGT_CHAR_HEIGHT, 0 ); This->Mode->CursorColumn = 0; This->Mode->CursorRow = (INT32) (mConsoleHeight - 1); } if (String[Index] < ' ' && String[Index] != '\t') { continue; } RenderChar (String[Index], &mCharacterBuffer[0].Raw); mGraphicsOutput->Blt ( mGraphicsOutput, &mCharacterBuffer[0].Pixel, EfiBltBufferToVideo, 0, 0, TGT_CHAR_WIDTH + This->Mode->CursorColumn * TGT_CHAR_WIDTH, TGT_CHAR_HEIGHT + This->Mode->CursorRow * TGT_CHAR_HEIGHT, TGT_CHAR_WIDTH, TGT_CHAR_HEIGHT, 0 ); ++This->Mode->CursorColumn; mConsoleMaxPosX = MAX (mConsoleMaxPosX, This->Mode->CursorColumn); } RenderCursor (This->Mode->CursorColumn, This->Mode->CursorRow, This->Mode->CursorVisible); return EFI_SUCCESS; } STATIC EFI_STATUS EFIAPI AsciiTextTestString ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN CHAR16 *String ) { return EFI_SUCCESS; } STATIC EFI_STATUS EFIAPI AsciiTextQueryMode ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN ModeNumber, OUT UINTN *Columns, OUT UINTN *Rows ) { if (ModeNumber != 0) { return EFI_UNSUPPORTED; } *Columns = mConsoleWidth; *Rows = mConsoleHeight; return EFI_SUCCESS; } STATIC EFI_STATUS EFIAPI AsciiTextSetMode ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN ModeNumber ) { if (ModeNumber != 0) { return EFI_UNSUPPORTED; } return EFI_SUCCESS; } STATIC EFI_STATUS EFIAPI AsciiTextSetAttribute ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN Attribute ) { UINT32 FgColor; UINT32 BgColor; if ((Attribute & ~0x7FU) != 0) { return EFI_UNSUPPORTED; } FgColor = BitFieldRead32 (Attribute, 0, 3); BgColor = BitFieldRead32 (Attribute, 4, 6); // // Black foreground means grey. // if (FgColor == 0) { FgColor = ARRAY_SIZE (mGraphicsEfiColors) / 2 - 1; } mForegroundColor.Raw = mGraphicsEfiColors[FgColor]; mBackgroundColor.Raw = mGraphicsEfiColors[BgColor]; This->Mode->Attribute = Attribute; return EFI_SUCCESS; } STATIC EFI_STATUS EFIAPI AsciiTextClearScreen ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This ) { mCursorOnscreen = FALSE; This->Mode->CursorColumn = 0; This->Mode->CursorRow = 0; if (mConsoleMaxPosX > 0) { mGraphicsOutput->Blt ( mGraphicsOutput, &mBackgroundColor.Pixel, EfiBltVideoFill, 0, 0, 0, 0, MIN ((mConsoleMaxPosX + 1) * TGT_CHAR_WIDTH, mGraphicsOutput->Mode->Info->HorizontalResolution), MIN ((mConsoleMaxPosY + 2) * TGT_CHAR_HEIGHT, mGraphicsOutput->Mode->Info->VerticalResolution), 0 ); } // // We do not reset max here, as we may still scroll (e.g. in shell via page buttons). // return EFI_SUCCESS; } STATIC EFI_STATUS EFIAPI AsciiTextSetCursorPosition ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN Column, IN UINTN Row ) { if (Column >= mConsoleWidth || Row >= mConsoleHeight) { return EFI_UNSUPPORTED; } This->Mode->CursorColumn = (INT32) Column; This->Mode->CursorRow = (INT32) Row; RenderCursor (This->Mode->CursorColumn, This->Mode->CursorRow, This->Mode->CursorVisible); return EFI_SUCCESS; } STATIC EFI_STATUS EFIAPI AsciiTextEnableCursor ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN BOOLEAN Visible ) { This->Mode->CursorVisible = Visible; RenderCursor (This->Mode->CursorColumn, This->Mode->CursorRow, This->Mode->CursorVisible); return EFI_SUCCESS; } STATIC EFI_SIMPLE_TEXT_OUTPUT_MODE mAsciiTextOutputMode = { .MaxMode = 1, .Mode = 0, .Attribute = 0, .CursorColumn = 0, .CursorRow = 0, .CursorVisible = FALSE, }; STATIC EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL mAsciiTextOutputProtocol = { AsciiTextReset, AsciiTextOutputString, AsciiTextTestString, AsciiTextQueryMode, AsciiTextSetMode, AsciiTextSetAttribute, AsciiTextClearScreen, AsciiTextSetCursorPosition, AsciiTextEnableCursor, &mAsciiTextOutputMode }; VOID OcInstallCustomConOut ( VOID ) { EFI_STATUS Status; UINTN UiScaleSize; UiScaleSize = sizeof (mFontScale); Status = gRT->GetVariable ( APPLE_UI_SCALE_VARIABLE_NAME, &gAppleVendorVariableGuid, NULL, &UiScaleSize, (VOID *) &mFontScale ); if (EFI_ERROR (Status) || mFontScale != 2) { mFontScale = 1; } DEBUG ((DEBUG_INFO, "OCC: Using builtin text renderer with %d scale\n", mFontScale)); Status = AsciiTextReset (&mAsciiTextOutputProtocol, TRUE); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_INFO, "OCC: Cannot setup ASCII output\n")); return; } gST->ConOut = &mAsciiTextOutputProtocol; gST->Hdr.CRC32 = 0; gBS->CalculateCrc32 ( gST, gST->Hdr.HeaderSize, &gST->Hdr.CRC32 ); OcConsoleControlSync (); }