2 Support for Basic Graphics operations.
4 BugBug: Currently *.BMP files are supported. This will be replaced
5 when Tiano graphics format is supported.
8 Copyright (c) 2006, Intel Corporation
9 All rights reserved. This program and the accompanying materials
10 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
22 #include <Protocol/SimpleTextOut.h>
23 #include <Protocol/OEMBadging.h>
24 #include <Protocol/ConsoleControl.h>
25 #include <Protocol/GraphicsOutput.h>
26 #include <Protocol/FirmwareVolume2.h>
27 #include <Protocol/UgaDraw.h>
28 #include <Protocol/HiiFont.h>
29 #include <Protocol/HiiImage.h>
33 #include <Library/GraphicsLib.h>
34 #include <Library/PrintLib.h>
35 #include <Library/BaseLib.h>
36 #include <Library/MemoryAllocationLib.h>
37 #include <Library/UefiBootServicesTableLib.h>
38 #include <Library/DebugLib.h>
39 #include <Library/BaseMemoryLib.h>
40 #include <Library/DxePiLib.h>
41 #include <Library/PcdLib.h>
43 STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors
[16] = {
44 { 0x00, 0x00, 0x00, 0x00 },
45 { 0x98, 0x00, 0x00, 0x00 },
46 { 0x00, 0x98, 0x00, 0x00 },
47 { 0x98, 0x98, 0x00, 0x00 },
48 { 0x00, 0x00, 0x98, 0x00 },
49 { 0x98, 0x00, 0x98, 0x00 },
50 { 0x00, 0x98, 0x98, 0x00 },
51 { 0x98, 0x98, 0x98, 0x00 },
52 { 0x10, 0x10, 0x10, 0x00 },
53 { 0xff, 0x10, 0x10, 0x00 },
54 { 0x10, 0xff, 0x10, 0x00 },
55 { 0xff, 0xff, 0x10, 0x00 },
56 { 0x10, 0x10, 0xff, 0x00 },
57 { 0xf0, 0x10, 0xff, 0x00 },
58 { 0x10, 0xff, 0xff, 0x00 },
59 { 0xff, 0xff, 0xff, 0x00 }
64 GetGraphicsBitMapFromFV (
65 IN EFI_GUID
*FileNameGuid
,
73 Return the graphics image file named FileNameGuid into Image and return it's
74 size in ImageSize. All Firmware Volumes (FV) in the system are searched for the
79 FileNameGuid - File Name of graphics file in the FV(s).
81 Image - Pointer to pointer to return graphics image. If NULL, a
82 buffer will be allocated.
84 ImageSize - Size of the graphics Image in bytes. Zero if no image found.
89 EFI_SUCCESS - Image and ImageSize are valid.
90 EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size
91 EFI_NOT_FOUND - FileNameGuid not found
95 return GetGraphicsBitMapFromFVEx (NULL
, FileNameGuid
, Image
, ImageSize
);
99 GetGraphicsBitMapFromFVEx (
100 IN EFI_HANDLE ImageHandle
,
101 IN EFI_GUID
*FileNameGuid
,
109 Return the graphics image file named FileNameGuid into Image and return it's
110 size in ImageSize. All Firmware Volumes (FV) in the system are searched for the
115 ImageHandle - The driver image handle of the caller. The parameter is used to
116 optimize the loading of the image file so that the FV from which
117 the driver image is loaded will be tried first.
119 FileNameGuid - File Name of graphics file in the FV(s).
121 Image - Pointer to pointer to return graphics image. If NULL, a
122 buffer will be allocated.
124 ImageSize - Size of the graphics Image in bytes. Zero if no image found.
129 EFI_SUCCESS - Image and ImageSize are valid.
130 EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size
131 EFI_NOT_FOUND - FileNameGuid not found
135 return PiLibGetSectionFromAnyFv (
148 IN UINTN BmpImageSize
,
149 IN OUT VOID
**GopBlt
,
150 IN OUT UINTN
*GopBltSize
,
151 OUT UINTN
*PixelHeight
,
152 OUT UINTN
*PixelWidth
158 Convert a *.BMP graphics image to a GOP/UGA blt buffer. If a NULL Blt buffer
159 is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt
160 buffer is passed in it will be used if it is big enough.
164 BmpImage - Pointer to BMP file
166 BmpImageSize - Number of bytes in BmpImage
168 GopBlt - Buffer containing GOP version of BmpImage.
170 GopBltSize - Size of GopBlt in bytes.
172 PixelHeight - Height of GopBlt/BmpImage in pixels
174 PixelWidth - Width of GopBlt/BmpImage in pixels
179 EFI_SUCCESS - GopBlt and GopBltSize are returned.
180 EFI_UNSUPPORTED - BmpImage is not a valid *.BMP image
181 EFI_BUFFER_TOO_SMALL - The passed in GopBlt buffer is not big enough.
182 GopBltSize will contain the required size.
183 EFI_OUT_OF_RESOURCES - No enough buffer to allocate
189 BMP_IMAGE_HEADER
*BmpHeader
;
190 BMP_COLOR_MAP
*BmpColorMap
;
191 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
;
192 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
200 BmpHeader
= (BMP_IMAGE_HEADER
*) BmpImage
;
201 if (BmpHeader
->CharB
!= 'B' || BmpHeader
->CharM
!= 'M') {
202 return EFI_UNSUPPORTED
;
205 if (BmpHeader
->CompressionType
!= 0) {
206 return EFI_UNSUPPORTED
;
210 // Calculate Color Map offset in the image.
213 BmpColorMap
= (BMP_COLOR_MAP
*) (Image
+ sizeof (BMP_IMAGE_HEADER
));
216 // Calculate graphics image data address in the image
218 Image
= ((UINT8
*) BmpImage
) + BmpHeader
->ImageOffset
;
221 BltBufferSize
= BmpHeader
->PixelWidth
* BmpHeader
->PixelHeight
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
223 if (*GopBlt
== NULL
) {
224 *GopBltSize
= BltBufferSize
;
225 *GopBlt
= AllocatePool (*GopBltSize
);
227 if (*GopBlt
== NULL
) {
228 return EFI_OUT_OF_RESOURCES
;
231 if (*GopBltSize
< BltBufferSize
) {
232 *GopBltSize
= BltBufferSize
;
233 return EFI_BUFFER_TOO_SMALL
;
237 *PixelWidth
= BmpHeader
->PixelWidth
;
238 *PixelHeight
= BmpHeader
->PixelHeight
;
241 // Convert image from BMP to Blt buffer format
244 for (Height
= 0; Height
< BmpHeader
->PixelHeight
; Height
++) {
245 Blt
= &BltBuffer
[(BmpHeader
->PixelHeight
- Height
- 1) * BmpHeader
->PixelWidth
];
246 for (Width
= 0; Width
< BmpHeader
->PixelWidth
; Width
++, Image
++, Blt
++) {
247 switch (BmpHeader
->BitPerPixel
) {
250 // Convert 1bit BMP to 24-bit color
252 for (Index
= 0; Index
< 8 && Width
< BmpHeader
->PixelWidth
; Index
++) {
253 Blt
->Red
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Red
;
254 Blt
->Green
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Green
;
255 Blt
->Blue
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Blue
;
266 // Convert BMP Palette to 24-bit color
268 Index
= (*Image
) >> 4;
269 Blt
->Red
= BmpColorMap
[Index
].Red
;
270 Blt
->Green
= BmpColorMap
[Index
].Green
;
271 Blt
->Blue
= BmpColorMap
[Index
].Blue
;
272 if (Width
< (BmpHeader
->PixelWidth
- 1)) {
275 Index
= (*Image
) & 0x0f;
276 Blt
->Red
= BmpColorMap
[Index
].Red
;
277 Blt
->Green
= BmpColorMap
[Index
].Green
;
278 Blt
->Blue
= BmpColorMap
[Index
].Blue
;
284 // Convert BMP Palette to 24-bit color
286 Blt
->Red
= BmpColorMap
[*Image
].Red
;
287 Blt
->Green
= BmpColorMap
[*Image
].Green
;
288 Blt
->Blue
= BmpColorMap
[*Image
].Blue
;
292 Blt
->Blue
= *Image
++;
293 Blt
->Green
= *Image
++;
299 gBS
->FreePool (*GopBlt
);
302 return EFI_UNSUPPORTED
;
308 ImageIndex
= (UINTN
) (Image
- ImageHeader
);
309 if ((ImageIndex
% 4) != 0) {
311 // Bmp Image starts each row on a 32-bit boundary!
313 Image
= Image
+ (4 - (ImageIndex
% 4));
328 Use Console Control Protocol to lock the Console In Spliter virtual handle.
329 This is the ConInHandle and ConIn handle in the EFI system table. All key
330 presses will be ignored until the Password is typed in. The only way to
331 disable the password is to type it in to a ConIn device.
334 Password - Password used to lock ConIn device
339 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo
341 EFI_UNSUPPORTED - Logo not found
346 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
348 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, (VOID
**) &ConsoleControl
);
349 if (EFI_ERROR (Status
)) {
350 return EFI_UNSUPPORTED
;
353 Status
= ConsoleControl
->LockStdIn (ConsoleControl
, Password
);
360 IN EFI_GUID
*LogoFile
366 Use Console Control to turn off UGA based Simple Text Out consoles from going
367 to the UGA device. Put up LogoFile on every UGA device that is a console
371 LogoFile - File name of logo to display on the center of the screen.
376 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo
378 EFI_UNSUPPORTED - Logo not found
382 return EnableQuietBootEx (LogoFile
, NULL
);
387 IN EFI_GUID
*LogoFile
,
388 IN EFI_HANDLE ImageHandle
394 Use Console Control to turn off GOP/UGA based Simple Text Out consoles from going
395 to the GOP/UGA device. Put up LogoFile on every GOP/UGA device that is a console
399 LogoFile - File name of logo to display on the center of the screen.
400 ImageHandle - The driver image handle of the caller. The parameter is used to
401 optimize the loading of the logo file so that the FV from which
402 the driver image is loaded will be tried first.
407 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo
409 EFI_UNSUPPORTED - Logo not found
414 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
415 EFI_OEM_BADGING_PROTOCOL
*Badging
;
424 EFI_BADGING_FORMAT Format
;
425 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute
;
430 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
431 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
434 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
436 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, (VOID
**)&ConsoleControl
);
437 if (EFI_ERROR (Status
)) {
438 return EFI_UNSUPPORTED
;
443 // Try to open GOP first
445 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiGraphicsOutputProtocolGuid
, (VOID
**)&GraphicsOutput
);
446 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
447 GraphicsOutput
= NULL
;
449 // Open GOP failed, try to open UGwhA
451 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiUgaDrawProtocolGuid
, (VOID
**)&UgaDraw
);
453 if (EFI_ERROR (Status
)) {
454 return EFI_UNSUPPORTED
;
458 Status
= gBS
->LocateProtocol (&gEfiOEMBadgingProtocolGuid
, NULL
, (VOID
**)&Badging
);
460 Status
= ConsoleControl
->SetMode (ConsoleControl
, EfiConsoleControlScreenGraphics
);
461 if (EFI_ERROR (Status
)) {
462 return EFI_UNSUPPORTED
;
465 if (GraphicsOutput
!= NULL
) {
466 SizeOfX
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
467 SizeOfY
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
468 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
469 Status
= UgaDraw
->GetMode (UgaDraw
, &SizeOfX
, &SizeOfY
, &ColorDepth
, &RefreshRate
);
470 if (EFI_ERROR (Status
)) {
471 return EFI_UNSUPPORTED
;
480 if (Badging
!= NULL
) {
481 Status
= Badging
->GetImage (
491 if (EFI_ERROR (Status
)) {
496 // Currently only support BMP format
498 if (Format
!= EfiBadgingFormatBMP
) {
499 gBS
->FreePool (ImageData
);
503 Status
= GetGraphicsBitMapFromFVEx (ImageHandle
, LogoFile
, (VOID
**) &ImageData
, &ImageSize
);
504 if (EFI_ERROR (Status
)) {
505 return EFI_UNSUPPORTED
;
510 Attribute
= EfiBadgingDisplayAttributeCenter
;
514 Status
= ConvertBmpToGopBlt (
522 if (EFI_ERROR (Status
)) {
523 gBS
->FreePool (ImageData
);
524 if (Badging
== NULL
) {
532 case EfiBadgingDisplayAttributeLeftTop
:
537 case EfiBadgingDisplayAttributeCenterTop
:
538 DestX
= (SizeOfX
- Width
) / 2;
542 case EfiBadgingDisplayAttributeRightTop
:
543 DestX
= (SizeOfX
- Width
- CoordinateX
);
544 DestY
= CoordinateY
;;
547 case EfiBadgingDisplayAttributeCenterRight
:
548 DestX
= (SizeOfX
- Width
- CoordinateX
);
549 DestY
= (SizeOfY
- Height
) / 2;
552 case EfiBadgingDisplayAttributeRightBottom
:
553 DestX
= (SizeOfX
- Width
- CoordinateX
);
554 DestY
= (SizeOfY
- Height
- CoordinateY
);
557 case EfiBadgingDisplayAttributeCenterBottom
:
558 DestX
= (SizeOfX
- Width
) / 2;
559 DestY
= (SizeOfY
- Height
- CoordinateY
);
562 case EfiBadgingDisplayAttributeLeftBottom
:
564 DestY
= (SizeOfY
- Height
- CoordinateY
);
567 case EfiBadgingDisplayAttributeCenterLeft
:
569 DestY
= (SizeOfY
- Height
) / 2;
572 case EfiBadgingDisplayAttributeCenter
:
573 DestX
= (SizeOfX
- Width
) / 2;
574 DestY
= (SizeOfY
- Height
) / 2;
583 if ((DestX
>= 0) && (DestY
>= 0)) {
584 if (GraphicsOutput
!= NULL
) {
585 Status
= GraphicsOutput
->Blt (
595 Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
597 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
598 Status
= UgaDraw
->Blt (
600 (EFI_UGA_PIXEL
*) Blt
,
601 EfiUgaBltBufferToVideo
,
608 Width
* sizeof (EFI_UGA_PIXEL
)
613 gBS
->FreePool (ImageData
);
616 if (Badging
== NULL
) {
633 Use Console Control to turn on GOP/UGA based Simple Text Out consoles. The GOP/UGA
634 Simple Text Out screens will now be synced up with all non GOP/UGA output devices
642 EFI_SUCCESS - GOP/UGA devices are back in text mode and synced up.
643 EFI_UNSUPPORTED - Logo not found
648 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
650 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, (VOID
**) &ConsoleControl
);
651 if (EFI_ERROR (Status
)) {
652 return EFI_UNSUPPORTED
;
655 return ConsoleControl
->SetMode (ConsoleControl
, EfiConsoleControlScreenText
);
660 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
661 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
,
662 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*Sto
,
665 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Foreground
,
666 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Background
,
674 Display string worker for: Print, PrintAt, IPrint, IPrintAt
678 GraphicsOutput - Graphics output protocol interface
680 UgaDraw - UGA draw protocol interface
682 Sto - Simple text out protocol interface
684 X - X coordinate to start printing
686 Y - Y coordinate to start printing
688 Foreground - Foreground color
690 Background - Background color
694 args - Print arguments
698 EFI_SUCCESS - success
699 EFI_OUT_OF_RESOURCES - out of resources
706 CHAR16
*UnicodeWeight
;
707 UINT32 HorizontalResolution
;
708 UINT32 VerticalResolution
;
713 EFI_HII_FONT_PROTOCOL
*HiiFont
;
714 EFI_IMAGE_OUTPUT
*Blt
;
715 EFI_FONT_DISPLAY_INFO
*FontInfo
;
718 // For now, allocate an arbitrarily long buffer
720 Buffer
= AllocateZeroPool (0x10000);
721 if (Buffer
== NULL
) {
722 return EFI_OUT_OF_RESOURCES
;
725 HorizontalResolution
= 0;
726 VerticalResolution
= 0;
730 if (GraphicsOutput
!= NULL
) {
731 HorizontalResolution
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
732 VerticalResolution
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
733 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
734 UgaDraw
->GetMode (UgaDraw
, &HorizontalResolution
, &VerticalResolution
, &ColorDepth
, &RefreshRate
);
736 Status
= EFI_UNSUPPORTED
;
740 ASSERT ((HorizontalResolution
!= 0) && (VerticalResolution
!=0));
742 ASSERT (GraphicsOutput
!= NULL
);
743 Status
= gBS
->LocateProtocol (&gEfiHiiFontProtocolGuid
, NULL
, (VOID
**) &HiiFont
);
744 if (EFI_ERROR (Status
)) {
748 UnicodeVSPrint (Buffer
, 0x10000, fmt
, args
);
750 UnicodeWeight
= (CHAR16
*) Buffer
;
752 for (Index
= 0; UnicodeWeight
[Index
] != 0; Index
++) {
753 if (UnicodeWeight
[Index
] == CHAR_BACKSPACE
||
754 UnicodeWeight
[Index
] == CHAR_LINEFEED
||
755 UnicodeWeight
[Index
] == CHAR_CARRIAGE_RETURN
) {
756 UnicodeWeight
[Index
] = 0;
760 BufferLen
= StrLen (Buffer
);
763 LineBufferLen
= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * HorizontalResolution
* EFI_GLYPH_HEIGHT
;
764 if (EFI_GLYPH_WIDTH
* EFI_GLYPH_HEIGHT
* sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * BufferLen
> LineBufferLen
) {
765 Status
= EFI_INVALID_PARAMETER
;
769 Blt
= (EFI_IMAGE_OUTPUT
*) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT
));
771 Status
= EFI_OUT_OF_RESOURCES
;
775 Blt
->Width
= (UINT16
) (HorizontalResolution
);
776 Blt
->Height
= (UINT16
) (VerticalResolution
);
777 Blt
->Image
.Screen
= GraphicsOutput
;
779 FontInfo
= (EFI_FONT_DISPLAY_INFO
*) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO
));
780 if (FontInfo
== NULL
) {
781 Status
= EFI_OUT_OF_RESOURCES
;
784 if (Foreground
!= NULL
) {
785 CopyMem (&FontInfo
->ForegroundColor
, Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
788 &FontInfo
->ForegroundColor
,
789 &mEfiColors
[Sto
->Mode
->Attribute
& 0x0f],
790 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
793 if (Background
!= NULL
) {
794 CopyMem (&FontInfo
->BackgroundColor
, Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
797 &FontInfo
->BackgroundColor
,
798 &mEfiColors
[Sto
->Mode
->Attribute
>> 4],
799 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
803 Status
= HiiFont
->StringToImage (
805 EFI_HII_IGNORE_IF_NO_GLYPH
| EFI_HII_DIRECT_TO_SCREEN
,
819 SafeFreePool (FontInfo
);
820 gBS
->FreePool (Buffer
);
828 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*ForeGround
, OPTIONAL
829 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BackGround
, OPTIONAL
837 Prints a formatted unicode string to the default console
841 X - X coordinate to start printing
843 Y - Y coordinate to start printing
845 ForeGround - Foreground color
847 BackGround - Background color
851 ... - Print arguments
855 Length of string printed to the console
860 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
861 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
862 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*Sto
;
866 VA_START (Args
, Fmt
);
868 Handle
= gST
->ConsoleOutHandle
;
870 Status
= gBS
->HandleProtocol (
872 &gEfiGraphicsOutputProtocolGuid
,
873 (VOID
**)&GraphicsOutput
877 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
878 GraphicsOutput
= NULL
;
880 Status
= gBS
->HandleProtocol (
882 &gEfiUgaDrawProtocolGuid
,
886 if (EFI_ERROR (Status
)) {
890 Status
= gBS
->HandleProtocol (
892 &gEfiSimpleTextOutProtocolGuid
,
896 if (EFI_ERROR (Status
)) {
900 return _IPrint (GraphicsOutput
, UgaDraw
, Sto
, X
, Y
, ForeGround
, BackGround
, Fmt
, Args
);