From 519f076a478a7da9ff4b9d5327a993b1fc2968e8 Mon Sep 17 00:00:00 2001 From: vanjeff Date: Mon, 24 Nov 2008 05:49:59 +0000 Subject: 1.retried graphics library class from MdePkg 2.retried graphics library instance from MdeModulePkg 3.Move EnableQuietBoot(), DisableQuietBoot() and LockKeyboards() into GenericBdsLib git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@6691 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Library/GenericBdsLib/BdsConsole.c | 493 +++++++++++++++++++++ .../Library/GenericBdsLib/GenericBdsLib.inf | 13 +- .../Library/GenericBdsLib/InternalBdsLib.h | 10 + 3 files changed, 514 insertions(+), 2 deletions(-) (limited to 'MdeModulePkg/Library/GenericBdsLib') diff --git a/MdeModulePkg/Library/GenericBdsLib/BdsConsole.c b/MdeModulePkg/Library/GenericBdsLib/BdsConsole.c index 376a3187be..999de49ba3 100644 --- a/MdeModulePkg/Library/GenericBdsLib/BdsConsole.c +++ b/MdeModulePkg/Library/GenericBdsLib/BdsConsole.c @@ -405,3 +405,496 @@ BdsLibConnectAllDefaultConsoles ( return EFI_SUCCESS; } + +/** + Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer + is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt + buffer is passed in it will be used if it is big enough. + + @param BmpImage Pointer to BMP file + @param BmpImageSize Number of bytes in BmpImage + @param GopBlt Buffer containing GOP version of BmpImage. + @param GopBltSize Size of GopBlt in bytes. + @param PixelHeight Height of GopBlt/BmpImage in pixels + @param PixelWidth Width of GopBlt/BmpImage in pixels + + @retval EFI_SUCCESS GopBlt and GopBltSize are returned. + @retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image + @retval EFI_BUFFER_TOO_SMALL The passed in GopBlt buffer is not big enough. + GopBltSize will contain the required size. + @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate. + +**/ +EFI_STATUS +ConvertBmpToGopBlt ( + IN VOID *BmpImage, + IN UINTN BmpImageSize, + IN OUT VOID **GopBlt, + IN OUT UINTN *GopBltSize, + OUT UINTN *PixelHeight, + OUT UINTN *PixelWidth + ) +{ + UINT8 *Image; + UINT8 *ImageHeader; + BMP_IMAGE_HEADER *BmpHeader; + BMP_COLOR_MAP *BmpColorMap; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; + UINTN BltBufferSize; + UINTN Index; + UINTN Height; + UINTN Width; + UINTN ImageIndex; + BOOLEAN IsAllocated; + + BmpHeader = (BMP_IMAGE_HEADER *) BmpImage; + + if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') { + return EFI_UNSUPPORTED; + } + + // + // Doesn't support compress. + // + if (BmpHeader->CompressionType != 0) { + return EFI_UNSUPPORTED; + } + + // + // Calculate Color Map offset in the image. + // + Image = BmpImage; + BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER)); + + // + // Calculate graphics image data address in the image + // + Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset; + ImageHeader = Image; + + // + // Calculate the BltBuffer needed size. + // + BltBufferSize = BmpHeader->PixelWidth * BmpHeader->PixelHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL); + IsAllocated = FALSE; + if (*GopBlt == NULL) { + // + // GopBlt is not allocated by caller. + // + *GopBltSize = BltBufferSize; + *GopBlt = AllocatePool (*GopBltSize); + IsAllocated = TRUE; + if (*GopBlt == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } else { + // + // GopBlt has been allocated by caller. + // + if (*GopBltSize < BltBufferSize) { + *GopBltSize = BltBufferSize; + return EFI_BUFFER_TOO_SMALL; + } + } + + *PixelWidth = BmpHeader->PixelWidth; + *PixelHeight = BmpHeader->PixelHeight; + + // + // Convert image from BMP to Blt buffer format + // + BltBuffer = *GopBlt; + for (Height = 0; Height < BmpHeader->PixelHeight; Height++) { + Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth]; + for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) { + switch (BmpHeader->BitPerPixel) { + case 1: + // + // Convert 1-bit (2 colors) BMP to 24-bit color + // + for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) { + Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red; + Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green; + Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue; + Blt++; + Width++; + } + + Blt --; + Width --; + break; + + case 4: + // + // Convert 4-bit (16 colors) BMP Palette to 24-bit color + // + Index = (*Image) >> 4; + Blt->Red = BmpColorMap[Index].Red; + Blt->Green = BmpColorMap[Index].Green; + Blt->Blue = BmpColorMap[Index].Blue; + if (Width < (BmpHeader->PixelWidth - 1)) { + Blt++; + Width++; + Index = (*Image) & 0x0f; + Blt->Red = BmpColorMap[Index].Red; + Blt->Green = BmpColorMap[Index].Green; + Blt->Blue = BmpColorMap[Index].Blue; + } + break; + + case 8: + // + // Convert 8-bit (256 colors) BMP Palette to 24-bit color + // + Blt->Red = BmpColorMap[*Image].Red; + Blt->Green = BmpColorMap[*Image].Green; + Blt->Blue = BmpColorMap[*Image].Blue; + break; + + case 24: + // + // It is 24-bit BMP. + // + Blt->Blue = *Image++; + Blt->Green = *Image++; + Blt->Red = *Image; + break; + + default: + // + // Other bit format BMP is not supported. + // + if (IsAllocated) { + FreePool (*GopBlt); + *GopBlt = NULL; + } + return EFI_UNSUPPORTED; + break; + }; + + } + + ImageIndex = (UINTN) (Image - ImageHeader); + if ((ImageIndex % 4) != 0) { + // + // Bmp Image starts each row on a 32-bit boundary! + // + Image = Image + (4 - (ImageIndex % 4)); + } + } + + return EFI_SUCCESS; +} + + +/** + Use Console Control Protocol to lock the Console In Spliter virtual handle. + This is the ConInHandle and ConIn handle in the EFI system table. All key + presses will be ignored until the Password is typed in. The only way to + disable the password is to type it in to a ConIn device. + + @param Password Password used to lock ConIn device. + + @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully. + @retval EFI_UNSUPPORTED Password not found. + +**/ +EFI_STATUS +EFIAPI +LockKeyboards ( + IN CHAR16 *Password + ) +{ + EFI_STATUS Status; + EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl; + + Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Status = ConsoleControl->LockStdIn (ConsoleControl, Password); + return Status; +} + + +/** + Use Console Control to turn off UGA based Simple Text Out consoles from going + to the UGA device. Put up LogoFile on every UGA device that is a console. + + @param LogoFile File name of logo to display on the center of the screen. + + @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed. + @retval EFI_UNSUPPORTED Logo not found. + +**/ +EFI_STATUS +EFIAPI +EnableQuietBoot ( + IN EFI_GUID *LogoFile OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl; + EFI_OEM_BADGING_PROTOCOL *Badging; + UINT32 SizeOfX; + UINT32 SizeOfY; + INTN DestX; + INTN DestY; + UINT8 *ImageData; + UINTN ImageSize; + UINTN BltSize; + UINT32 Instance; + EFI_BADGING_FORMAT Format; + EFI_BADGING_DISPLAY_ATTRIBUTE Attribute; + UINTN CoordinateX; + UINTN CoordinateY; + UINTN Height; + UINTN Width; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; + EFI_UGA_DRAW_PROTOCOL *UgaDraw; + UINT32 ColorDepth; + UINT32 RefreshRate; + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; + + Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + UgaDraw = NULL; + // + // Try to open GOP first + // + Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput); + if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) { + GraphicsOutput = NULL; + // + // Open GOP failed, try to open UGA + // + Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw); + } + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Badging = NULL; + Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging); + + // + // Set console control to graphics mode. + // + Status = ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + if (GraphicsOutput != NULL) { + SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution; + SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution; + } else if (FeaturePcdGet (PcdUgaConsumeSupport)) { + Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + } else { + return EFI_UNSUPPORTED; + } + + Instance = 0; + while (1) { + ImageData = NULL; + ImageSize = 0; + + if (Badging != NULL) { + // + // Get image from OEMBadging protocol. + // + Status = Badging->GetImage ( + Badging, + &Instance, + &Format, + &ImageData, + &ImageSize, + &Attribute, + &CoordinateX, + &CoordinateY + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Currently only support BMP format. + // + if (Format != EfiBadgingFormatBMP) { + if (ImageData != NULL) { + FreePool (ImageData); + } + continue; + } + } else { + // + // Get the specified image from FV. + // + Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **) &ImageData, &ImageSize); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + CoordinateX = 0; + CoordinateY = 0; + Attribute = EfiBadgingDisplayAttributeCenter; + } + + Blt = NULL; + Status = ConvertBmpToGopBlt ( + ImageData, + ImageSize, + (VOID **) &Blt, + &BltSize, + &Height, + &Width + ); + if (EFI_ERROR (Status)) { + if (ImageData != NULL) { + FreePool (ImageData); + } + if (Badging == NULL) { + return Status; + } else { + continue; + } + } + + // + // Caculate the display position according to Attribute. + // + switch (Attribute) { + case EfiBadgingDisplayAttributeLeftTop: + DestX = CoordinateX; + DestY = CoordinateY; + break; + + case EfiBadgingDisplayAttributeCenterTop: + DestX = (SizeOfX - Width) / 2; + DestY = CoordinateY; + break; + + case EfiBadgingDisplayAttributeRightTop: + DestX = (SizeOfX - Width - CoordinateX); + DestY = CoordinateY;; + break; + + case EfiBadgingDisplayAttributeCenterRight: + DestX = (SizeOfX - Width - CoordinateX); + DestY = (SizeOfY - Height) / 2; + break; + + case EfiBadgingDisplayAttributeRightBottom: + DestX = (SizeOfX - Width - CoordinateX); + DestY = (SizeOfY - Height - CoordinateY); + break; + + case EfiBadgingDisplayAttributeCenterBottom: + DestX = (SizeOfX - Width) / 2; + DestY = (SizeOfY - Height - CoordinateY); + break; + + case EfiBadgingDisplayAttributeLeftBottom: + DestX = CoordinateX; + DestY = (SizeOfY - Height - CoordinateY); + break; + + case EfiBadgingDisplayAttributeCenterLeft: + DestX = CoordinateX; + DestY = (SizeOfY - Height) / 2; + break; + + case EfiBadgingDisplayAttributeCenter: + DestX = (SizeOfX - Width) / 2; + DestY = (SizeOfY - Height) / 2; + break; + + default: + DestX = CoordinateX; + DestY = CoordinateY; + break; + } + + if ((DestX >= 0) && (DestY >= 0)) { + if (GraphicsOutput != NULL) { + Status = GraphicsOutput->Blt ( + GraphicsOutput, + Blt, + EfiBltBufferToVideo, + 0, + 0, + (UINTN) DestX, + (UINTN) DestY, + Width, + Height, + Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + ); + } else if (FeaturePcdGet (PcdUgaConsumeSupport)) { + Status = UgaDraw->Blt ( + UgaDraw, + (EFI_UGA_PIXEL *) Blt, + EfiUgaBltBufferToVideo, + 0, + 0, + (UINTN) DestX, + (UINTN) DestY, + Width, + Height, + Width * sizeof (EFI_UGA_PIXEL) + ); + } else { + Status = EFI_UNSUPPORTED; + } + } + + if (ImageData != NULL) { + FreePool (ImageData); + } + if (Blt != NULL) { + FreePool (Blt); + } + + if (Badging == NULL) { + break; + } + } + + return Status; +} + +/** + Use Console Control to turn on UGA based Simple Text Out consoles. The UGA + Simple Text Out screens will now be synced up with all non UGA output devices + + @retval EFI_SUCCESS UGA devices are back in text mode and synced up. + @retval EFI_UNSUPPORTED Logo not found + +**/ +EFI_STATUS +EFIAPI +DisableQuietBoot ( + VOID + ) +{ + EFI_STATUS Status; + EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl; + + Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + // + // Set console control to text mode. + // + return ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText); +} + diff --git a/MdeModulePkg/Library/GenericBdsLib/GenericBdsLib.inf b/MdeModulePkg/Library/GenericBdsLib/GenericBdsLib.inf index ea59766e49..34100d2668 100644 --- a/MdeModulePkg/Library/GenericBdsLib/GenericBdsLib.inf +++ b/MdeModulePkg/Library/GenericBdsLib/GenericBdsLib.inf @@ -68,7 +68,8 @@ PcdLib PerformanceLib TimerLib - + PcdLib + DxeServicesLib [Guids] gEfiVT100PlusGuid # ALWAYS_CONSUMED @@ -93,12 +94,20 @@ gEfiDebugPortProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiSimpleTextInProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiBlockIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED - gEfiFirmwareVolume2ProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiFirmwareVolume2ProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiLegacyBiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiCpuArchProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiFirmwareVolumeDispatchProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiAcpiS3SaveProtocolGuid + gEfiGraphicsOutputProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiUgaDrawProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiConsoleControlProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiOEMBadgingProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiHiiFontProtocolGuid # PROTOCOL ALWAYS_CONSUMED + +[FeaturePcd.common] + gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdPlatformBootTimeOutDefault diff --git a/MdeModulePkg/Library/GenericBdsLib/InternalBdsLib.h b/MdeModulePkg/Library/GenericBdsLib/InternalBdsLib.h index a0defe6376..b1bf7fcdda 100644 --- a/MdeModulePkg/Library/GenericBdsLib/InternalBdsLib.h +++ b/MdeModulePkg/Library/GenericBdsLib/InternalBdsLib.h @@ -35,6 +35,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include +#include +#include +#include +#include +#include + #include #include @@ -42,6 +49,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #include #include @@ -60,6 +68,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include +#include #define PERFORMANCE_SIGNATURE EFI_SIGNATURE_32 ('P', 'e', 'r', 'f') #define PERF_TOKEN_SIZE 28 -- cgit v1.2.3