]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Foundation/Library/Dxe/Graphics/Graphics.c
Add in the 1st version of ECP.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / Graphics / Graphics.c
diff --git a/EdkCompatibilityPkg/Foundation/Library/Dxe/Graphics/Graphics.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/Graphics/Graphics.c
new file mode 100644 (file)
index 0000000..80d9b72
--- /dev/null
@@ -0,0 +1,619 @@
+/*++\r
+\r
+Copyright (c) 2004 - 2007, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  Graphics.c\r
+\r
+Abstract:\r
+\r
+  Support for Basic Graphics operations.\r
+\r
+  BugBug: Currently *.BMP files are supported. This will be replaced\r
+          when Tiano graphics format is supported.\r
+\r
+--*/\r
+\r
+#include "Tiano.h"\r
+#include "EfiDriverLib.h"\r
+#include "GraphicsLib.h"\r
+\r
+EFI_STATUS\r
+GetGraphicsBitMapFromFV (\r
+  IN  EFI_GUID      *FileNameGuid,\r
+  OUT VOID          **Image,\r
+  OUT UINTN         *ImageSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Return the graphics image file named FileNameGuid into Image and return it's\r
+  size in ImageSize. All Firmware Volumes (FV) in the system are searched for the\r
+  file name.\r
+\r
+Arguments:\r
+\r
+  FileNameGuid  - File Name of graphics file in the FV(s).\r
+\r
+  Image         - Pointer to pointer to return graphics image.  If NULL, a \r
+                  buffer will be allocated.\r
+\r
+  ImageSize     - Size of the graphics Image in bytes. Zero if no image found.\r
+\r
+\r
+Returns: \r
+\r
+  EFI_SUCCESS          - Image and ImageSize are valid. \r
+  EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size\r
+  EFI_NOT_FOUND        - FileNameGuid not found\r
+\r
+--*/\r
+{\r
+  return GetGraphicsBitMapFromFVEx (NULL, FileNameGuid, Image, ImageSize);\r
+}\r
+\r
+EFI_STATUS\r
+GetGraphicsBitMapFromFVEx (\r
+  IN  EFI_HANDLE    ImageHandle,\r
+  IN  EFI_GUID      *FileNameGuid,\r
+  OUT VOID          **Image,\r
+  OUT UINTN         *ImageSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Return the graphics image file named FileNameGuid into Image and return it's\r
+  size in ImageSize. All Firmware Volumes (FV) in the system are searched for the\r
+  file name.\r
+\r
+Arguments:\r
+\r
+  ImageHandle   - The driver image handle of the caller. The parameter is used to\r
+                  optimize the loading of the image file so that the FV from which\r
+                  the driver image is loaded will be tried first. \r
+\r
+  FileNameGuid  - File Name of graphics file in the FV(s).\r
+\r
+  Image         - Pointer to pointer to return graphics image.  If NULL, a \r
+                  buffer will be allocated.\r
+\r
+  ImageSize     - Size of the graphics Image in bytes. Zero if no image found.\r
+\r
+\r
+Returns: \r
+\r
+  EFI_SUCCESS          - Image and ImageSize are valid. \r
+  EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size\r
+  EFI_NOT_FOUND        - FileNameGuid not found\r
+\r
+--*/\r
+{\r
+  return GetImageEx (\r
+           ImageHandle,\r
+           &gEfiDefaultBmpLogoGuid,\r
+           EFI_SECTION_RAW,\r
+           Image,\r
+           ImageSize,\r
+           FALSE\r
+           );\r
+}\r
+\r
+\r
+EFI_STATUS\r
+ConvertBmpToGopBlt (\r
+  IN  VOID      *BmpImage,\r
+  IN  UINTN     BmpImageSize,\r
+  IN OUT VOID   **GopBlt,\r
+  IN OUT UINTN  *GopBltSize,\r
+  OUT UINTN     *PixelHeight,\r
+  OUT UINTN     *PixelWidth\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Convert a *.BMP graphics image to a GOP/UGA blt buffer. If a NULL Blt buffer\r
+  is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt\r
+  buffer is passed in it will be used if it is big enough.\r
+\r
+Arguments:\r
+\r
+  BmpImage      - Pointer to BMP file\r
+\r
+  BmpImageSize  - Number of bytes in BmpImage\r
+\r
+  GopBlt        - Buffer containing GOP version of BmpImage.\r
+\r
+  GopBltSize    - Size of GopBlt in bytes.\r
+\r
+  PixelHeight   - Height of GopBlt/BmpImage in pixels\r
+\r
+  PixelWidth    - Width of GopBlt/BmpImage in pixels\r
+\r
+\r
+Returns: \r
+\r
+  EFI_SUCCESS           - GopBlt and GopBltSize are returned. \r
+  EFI_UNSUPPORTED       - BmpImage is not a valid *.BMP image\r
+  EFI_BUFFER_TOO_SMALL  - The passed in GopBlt buffer is not big enough.\r
+                          GopBltSize will contain the required size.\r
+  EFI_OUT_OF_RESOURCES  - No enough buffer to allocate\r
+\r
+--*/\r
+{\r
+  UINT8                         *Image;\r
+  UINT8                         *ImageHeader;\r
+  BMP_IMAGE_HEADER              *BmpHeader;\r
+  BMP_COLOR_MAP                 *BmpColorMap;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
+  UINTN                         BltBufferSize;\r
+  UINTN                         Index;\r
+  UINTN                         Height;\r
+  UINTN                         Width;\r
+  UINTN                         ImageIndex;\r
+  BOOLEAN                       IsAllocated;\r
+\r
+  BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;\r
+  if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (BmpHeader->CompressionType != 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Calculate Color Map offset in the image.\r
+  //\r
+  Image       = BmpImage;\r
+  BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));\r
+\r
+  //\r
+  // Calculate graphics image data address in the image\r
+  //\r
+  Image         = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;\r
+  ImageHeader   = Image;\r
+\r
+  BltBufferSize = BmpHeader->PixelWidth * BmpHeader->PixelHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
+  IsAllocated   = FALSE;\r
+  if (*GopBlt == NULL) {\r
+    *GopBltSize = BltBufferSize;\r
+    *GopBlt     = EfiLibAllocatePool (*GopBltSize);\r
+    IsAllocated = TRUE;\r
+    if (*GopBlt == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+  } else {\r
+    if (*GopBltSize < BltBufferSize) {\r
+      *GopBltSize = BltBufferSize;\r
+      return EFI_BUFFER_TOO_SMALL;\r
+    }\r
+  }\r
+\r
+  *PixelWidth   = BmpHeader->PixelWidth;\r
+  *PixelHeight  = BmpHeader->PixelHeight;\r
+\r
+  //\r
+  // Convert image from BMP to Blt buffer format\r
+  //\r
+  BltBuffer = *GopBlt;\r
+  for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {\r
+    Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];\r
+    for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {\r
+      switch (BmpHeader->BitPerPixel) {\r
+      case 1:\r
+        //\r
+        // Convert 1bit BMP to 24-bit color\r
+        //\r
+        for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {\r
+          Blt->Red    = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;\r
+          Blt->Green  = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;\r
+          Blt->Blue   = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;\r
+          Blt++;\r
+          Width++;\r
+        }\r
+\r
+        Blt --;\r
+        Width --;\r
+        break;\r
+\r
+      case 4:\r
+        //\r
+        // Convert BMP Palette to 24-bit color\r
+        //\r
+        Index       = (*Image) >> 4;\r
+        Blt->Red    = BmpColorMap[Index].Red;\r
+        Blt->Green  = BmpColorMap[Index].Green;\r
+        Blt->Blue   = BmpColorMap[Index].Blue;\r
+        if (Width < (BmpHeader->PixelWidth - 1)) {\r
+          Blt++;\r
+          Width++;\r
+          Index       = (*Image) & 0x0f;\r
+          Blt->Red    = BmpColorMap[Index].Red;\r
+          Blt->Green  = BmpColorMap[Index].Green;\r
+          Blt->Blue   = BmpColorMap[Index].Blue;\r
+        }\r
+        break;\r
+\r
+      case 8:\r
+        //\r
+        // Convert BMP Palette to 24-bit color\r
+        //\r
+        Blt->Red    = BmpColorMap[*Image].Red;\r
+        Blt->Green  = BmpColorMap[*Image].Green;\r
+        Blt->Blue   = BmpColorMap[*Image].Blue;\r
+        break;\r
+\r
+      case 24:\r
+        Blt->Blue   = *Image++;\r
+        Blt->Green  = *Image++;\r
+        Blt->Red    = *Image;\r
+        break;\r
+\r
+      default:\r
+        if (IsAllocated) {\r
+          gBS->FreePool (*GopBlt);\r
+          *GopBlt = NULL;\r
+        }\r
+        return EFI_UNSUPPORTED;\r
+        break;\r
+      };\r
+\r
+    }\r
+\r
+    ImageIndex = (UINTN) (Image - ImageHeader);\r
+    if ((ImageIndex % 4) != 0) {\r
+      //\r
+      // Bmp Image starts each row on a 32-bit boundary!\r
+      //\r
+      Image = Image + (4 - (ImageIndex % 4));\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+LockKeyboards (\r
+  IN  CHAR16    *Password\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Use Console Control Protocol to lock the Console In Spliter virtual handle. \r
+  This is the ConInHandle and ConIn handle in the EFI system table. All key\r
+  presses will be ignored until the Password is typed in. The only way to\r
+  disable the password is to type it in to a ConIn device.\r
+\r
+Arguments:\r
+  Password - Password used to lock ConIn device\r
+\r
+\r
+Returns: \r
+\r
+  EFI_SUCCESS     - ConsoleControl has been flipped to graphics and logo\r
+                          displayed.\r
+  EFI_UNSUPPORTED - Logo not found\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_CONSOLE_CONTROL_PROTOCOL  *ConsoleControl;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID**)&ConsoleControl);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Status = ConsoleControl->LockStdIn (ConsoleControl, Password);\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EnableQuietBoot (\r
+  IN  EFI_GUID  *LogoFile\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Use Console Control to turn off UGA based Simple Text Out consoles from going\r
+  to the UGA device. Put up LogoFile on every UGA device that is a console\r
+\r
+Arguments:\r
+\r
+  LogoFile - File name of logo to display on the center of the screen.\r
+\r
+\r
+Returns: \r
+\r
+  EFI_SUCCESS           - ConsoleControl has been flipped to graphics and logo\r
+                          displayed.\r
+  EFI_UNSUPPORTED       - Logo not found\r
+\r
+--*/\r
+{\r
+  return EnableQuietBootEx (LogoFile, NULL);\r
+}\r
+\r
+EFI_STATUS\r
+EnableQuietBootEx (\r
+  IN  EFI_GUID    *LogoFile,\r
+  IN  EFI_HANDLE  ImageHandle\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Use Console Control to turn off GOP/UGA based Simple Text Out consoles from going\r
+  to the GOP/UGA device. Put up LogoFile on every GOP/UGA device that is a console\r
+\r
+Arguments:\r
+\r
+  LogoFile    - File name of logo to display on the center of the screen.\r
+  ImageHandle - The driver image handle of the caller. The parameter is used to\r
+                optimize the loading of the logo file so that the FV from which\r
+                the driver image is loaded will be tried first.\r
+\r
+\r
+Returns: \r
+\r
+  EFI_SUCCESS           - ConsoleControl has been flipped to graphics and logo\r
+                          displayed.\r
+  EFI_UNSUPPORTED       - Logo not found\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_CONSOLE_CONTROL_PROTOCOL  *ConsoleControl;\r
+  EFI_OEM_BADGING_PROTOCOL      *Badging;\r
+  UINT32                        SizeOfX;\r
+  UINT32                        SizeOfY;\r
+  INTN                          DestX;\r
+  INTN                          DestY;\r
+  UINT8                         *ImageData;\r
+  UINTN                         ImageSize;\r
+  UINTN                         BltSize;\r
+  UINT32                        Instance;\r
+  EFI_BADGING_FORMAT            Format;\r
+  EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;\r
+  UINTN                         CoordinateX;\r
+  UINTN                         CoordinateY;\r
+  UINTN                         Height;\r
+  UINTN                         Width;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
+  EFI_UGA_DRAW_PROTOCOL         *UgaDraw;\r
+  UINT32                        ColorDepth;\r
+  UINT32                        RefreshRate;\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL  *GraphicsOutput;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID**)&ConsoleControl);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  UgaDraw = NULL;\r
+  //\r
+  // Try to open GOP first\r
+  //\r
+  Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID**)&GraphicsOutput);\r
+  if (EFI_ERROR (Status)) {\r
+    GraphicsOutput = NULL;\r
+    //\r
+    // Open GOP failed, try to open UGA\r
+    //\r
+    Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID**)&UgaDraw);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+  }\r
+\r
+  Badging = NULL;\r
+  Status  = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID**)&Badging);\r
+\r
+  ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics);\r
+\r
+  if (GraphicsOutput != NULL) {\r
+    SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
+    SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
+  } else {\r
+    Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+  }\r
+\r
+  Instance = 0;\r
+  while (1) {\r
+    ImageData = NULL;\r
+    ImageSize = 0;\r
+\r
+    if (Badging != NULL) {\r
+      Status = Badging->GetImage (\r
+                          Badging,\r
+                          &Instance,\r
+                          &Format,\r
+                          &ImageData,\r
+                          &ImageSize,\r
+                          &Attribute,\r
+                          &CoordinateX,\r
+                          &CoordinateY\r
+                          );\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+\r
+      //\r
+      // Currently only support BMP format\r
+      //\r
+      if (Format != EfiBadgingFormatBMP) {\r
+        gBS->FreePool (ImageData);\r
+        continue;\r
+      }\r
+    } else {\r
+      Status = GetGraphicsBitMapFromFVEx (ImageHandle, LogoFile, &ImageData, &ImageSize);\r
+      if (EFI_ERROR (Status)) {\r
+        return EFI_UNSUPPORTED;\r
+      }\r
+\r
+      CoordinateX = 0;\r
+      CoordinateY = 0;\r
+      Attribute   = EfiBadgingDisplayAttributeCenter;\r
+    }\r
+\r
+    Blt = NULL;\r
+    Status = ConvertBmpToGopBlt (\r
+              ImageData,\r
+              ImageSize,\r
+              (VOID**)&Blt,\r
+              &BltSize,\r
+              &Height,\r
+              &Width\r
+              );\r
+    if (EFI_ERROR (Status)) {\r
+      gBS->FreePool (ImageData);\r
+      if (Badging == NULL) {\r
+        return Status;\r
+      } else {\r
+        continue;\r
+      }\r
+    }\r
+\r
+    switch (Attribute) {\r
+    case EfiBadgingDisplayAttributeLeftTop:\r
+      DestX = CoordinateX;\r
+      DestY = CoordinateY;\r
+      break;\r
+\r
+    case EfiBadgingDisplayAttributeCenterTop:\r
+      DestX = (SizeOfX - Width) / 2;\r
+      DestY = CoordinateY;\r
+      break;\r
+\r
+    case EfiBadgingDisplayAttributeRightTop:\r
+      DestX = (SizeOfX - Width - CoordinateX);\r
+      DestY = CoordinateY;;\r
+      break;\r
+\r
+    case EfiBadgingDisplayAttributeCenterRight:\r
+      DestX = (SizeOfX - Width - CoordinateX);\r
+      DestY = (SizeOfY - Height) / 2;\r
+      break;\r
+\r
+    case EfiBadgingDisplayAttributeRightBottom:\r
+      DestX = (SizeOfX - Width - CoordinateX);\r
+      DestY = (SizeOfY - Height - CoordinateY);\r
+      break;\r
+\r
+    case EfiBadgingDisplayAttributeCenterBottom:\r
+      DestX = (SizeOfX - Width) / 2;\r
+      DestY = (SizeOfY - Height - CoordinateY);\r
+      break;\r
+\r
+    case EfiBadgingDisplayAttributeLeftBottom:\r
+      DestX = CoordinateX;\r
+      DestY = (SizeOfY - Height - CoordinateY);\r
+      break;\r
+\r
+    case EfiBadgingDisplayAttributeCenterLeft:\r
+      DestX = CoordinateX;\r
+      DestY = (SizeOfY - Height) / 2;\r
+      break;\r
+\r
+    case EfiBadgingDisplayAttributeCenter:\r
+      DestX = (SizeOfX - Width) / 2;\r
+      DestY = (SizeOfY - Height) / 2;\r
+      break;\r
+\r
+    default:\r
+      DestX = CoordinateX;\r
+      DestY = CoordinateY;\r
+      break;\r
+    }\r
+\r
+    if ((DestX >= 0) && (DestY >= 0)) {\r
+      if (GraphicsOutput != NULL) {\r
+        Status = GraphicsOutput->Blt (\r
+                            GraphicsOutput,\r
+                            Blt,\r
+                            EfiBltBufferToVideo,\r
+                            0,\r
+                            0,\r
+                            (UINTN) DestX,\r
+                            (UINTN) DestY,\r
+                            Width,\r
+                            Height,\r
+                            Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
+                            );\r
+      } else {\r
+        Status = UgaDraw->Blt (\r
+                            UgaDraw,\r
+                            (EFI_UGA_PIXEL *) Blt,\r
+                            EfiUgaBltBufferToVideo,\r
+                            0,\r
+                            0,\r
+                            (UINTN) DestX,\r
+                            (UINTN) DestY,\r
+                            Width,\r
+                            Height,\r
+                            Width * sizeof (EFI_UGA_PIXEL)\r
+                            );\r
+      }\r
+    }\r
+\r
+    gBS->FreePool (ImageData);\r
+    gBS->FreePool (Blt);\r
+\r
+    if (Badging == NULL) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+DisableQuietBoot (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Use Console Control to turn on GOP/UGA based Simple Text Out consoles. The GOP/UGA \r
+  Simple Text Out screens will now be synced up with all non GOP/UGA output devices\r
+\r
+Arguments:\r
+\r
+  NONE\r
+\r
+Returns: \r
+\r
+  EFI_SUCCESS           - GOP/UGA devices are back in text mode and synced up.\r
+  EFI_UNSUPPORTED       - Logo not found\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_CONSOLE_CONTROL_PROTOCOL  *ConsoleControl;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID**)&ConsoleControl);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  return ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);\r
+}\r