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
;
474 return EFI_UNSUPPORTED
;
482 if (Badging
!= NULL
) {
483 Status
= Badging
->GetImage (
493 if (EFI_ERROR (Status
)) {
498 // Currently only support BMP format
500 if (Format
!= EfiBadgingFormatBMP
) {
501 gBS
->FreePool (ImageData
);
505 Status
= GetGraphicsBitMapFromFVEx (ImageHandle
, LogoFile
, (VOID
**) &ImageData
, &ImageSize
);
506 if (EFI_ERROR (Status
)) {
507 return EFI_UNSUPPORTED
;
512 Attribute
= EfiBadgingDisplayAttributeCenter
;
516 Status
= ConvertBmpToGopBlt (
524 if (EFI_ERROR (Status
)) {
525 gBS
->FreePool (ImageData
);
526 if (Badging
== NULL
) {
534 case EfiBadgingDisplayAttributeLeftTop
:
539 case EfiBadgingDisplayAttributeCenterTop
:
540 DestX
= (SizeOfX
- Width
) / 2;
544 case EfiBadgingDisplayAttributeRightTop
:
545 DestX
= (SizeOfX
- Width
- CoordinateX
);
546 DestY
= CoordinateY
;;
549 case EfiBadgingDisplayAttributeCenterRight
:
550 DestX
= (SizeOfX
- Width
- CoordinateX
);
551 DestY
= (SizeOfY
- Height
) / 2;
554 case EfiBadgingDisplayAttributeRightBottom
:
555 DestX
= (SizeOfX
- Width
- CoordinateX
);
556 DestY
= (SizeOfY
- Height
- CoordinateY
);
559 case EfiBadgingDisplayAttributeCenterBottom
:
560 DestX
= (SizeOfX
- Width
) / 2;
561 DestY
= (SizeOfY
- Height
- CoordinateY
);
564 case EfiBadgingDisplayAttributeLeftBottom
:
566 DestY
= (SizeOfY
- Height
- CoordinateY
);
569 case EfiBadgingDisplayAttributeCenterLeft
:
571 DestY
= (SizeOfY
- Height
) / 2;
574 case EfiBadgingDisplayAttributeCenter
:
575 DestX
= (SizeOfX
- Width
) / 2;
576 DestY
= (SizeOfY
- Height
) / 2;
585 if ((DestX
>= 0) && (DestY
>= 0)) {
586 if (GraphicsOutput
!= NULL
) {
587 Status
= GraphicsOutput
->Blt (
597 Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
599 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
600 Status
= UgaDraw
->Blt (
602 (EFI_UGA_PIXEL
*) Blt
,
603 EfiUgaBltBufferToVideo
,
610 Width
* sizeof (EFI_UGA_PIXEL
)
613 Status
= EFI_UNSUPPORTED
;
617 gBS
->FreePool (ImageData
);
620 if (Badging
== NULL
) {
637 Use Console Control to turn on GOP/UGA based Simple Text Out consoles. The GOP/UGA
638 Simple Text Out screens will now be synced up with all non GOP/UGA output devices
646 EFI_SUCCESS - GOP/UGA devices are back in text mode and synced up.
647 EFI_UNSUPPORTED - Logo not found
652 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
654 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, (VOID
**) &ConsoleControl
);
655 if (EFI_ERROR (Status
)) {
656 return EFI_UNSUPPORTED
;
659 return ConsoleControl
->SetMode (ConsoleControl
, EfiConsoleControlScreenText
);
664 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
665 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
,
666 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*Sto
,
669 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Foreground
,
670 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Background
,
678 Display string worker for: Print, PrintAt, IPrint, IPrintAt
682 GraphicsOutput - Graphics output protocol interface
684 UgaDraw - UGA draw protocol interface
686 Sto - Simple text out protocol interface
688 X - X coordinate to start printing
690 Y - Y coordinate to start printing
692 Foreground - Foreground color
694 Background - Background color
698 args - Print arguments
702 EFI_SUCCESS - success
703 EFI_OUT_OF_RESOURCES - out of resources
710 CHAR16
*UnicodeWeight
;
711 UINT32 HorizontalResolution
;
712 UINT32 VerticalResolution
;
717 EFI_HII_FONT_PROTOCOL
*HiiFont
;
718 EFI_IMAGE_OUTPUT
*Blt
;
719 EFI_FONT_DISPLAY_INFO
*FontInfo
;
722 // For now, allocate an arbitrarily long buffer
724 Buffer
= AllocateZeroPool (0x10000);
725 if (Buffer
== NULL
) {
726 return EFI_OUT_OF_RESOURCES
;
729 HorizontalResolution
= 0;
730 VerticalResolution
= 0;
734 if (GraphicsOutput
!= NULL
) {
735 HorizontalResolution
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
736 VerticalResolution
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
737 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
738 UgaDraw
->GetMode (UgaDraw
, &HorizontalResolution
, &VerticalResolution
, &ColorDepth
, &RefreshRate
);
740 Status
= EFI_UNSUPPORTED
;
744 ASSERT ((HorizontalResolution
!= 0) && (VerticalResolution
!=0));
746 ASSERT (GraphicsOutput
!= NULL
);
747 Status
= gBS
->LocateProtocol (&gEfiHiiFontProtocolGuid
, NULL
, (VOID
**) &HiiFont
);
748 if (EFI_ERROR (Status
)) {
752 UnicodeVSPrint (Buffer
, 0x10000, fmt
, args
);
754 UnicodeWeight
= (CHAR16
*) Buffer
;
756 for (Index
= 0; UnicodeWeight
[Index
] != 0; Index
++) {
757 if (UnicodeWeight
[Index
] == CHAR_BACKSPACE
||
758 UnicodeWeight
[Index
] == CHAR_LINEFEED
||
759 UnicodeWeight
[Index
] == CHAR_CARRIAGE_RETURN
) {
760 UnicodeWeight
[Index
] = 0;
764 BufferLen
= StrLen (Buffer
);
767 LineBufferLen
= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * HorizontalResolution
* EFI_GLYPH_HEIGHT
;
768 if (EFI_GLYPH_WIDTH
* EFI_GLYPH_HEIGHT
* sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * BufferLen
> LineBufferLen
) {
769 Status
= EFI_INVALID_PARAMETER
;
773 Blt
= (EFI_IMAGE_OUTPUT
*) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT
));
775 Status
= EFI_OUT_OF_RESOURCES
;
779 Blt
->Width
= (UINT16
) (HorizontalResolution
);
780 Blt
->Height
= (UINT16
) (VerticalResolution
);
781 Blt
->Image
.Screen
= GraphicsOutput
;
783 FontInfo
= (EFI_FONT_DISPLAY_INFO
*) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO
));
784 if (FontInfo
== NULL
) {
785 Status
= EFI_OUT_OF_RESOURCES
;
788 if (Foreground
!= NULL
) {
789 CopyMem (&FontInfo
->ForegroundColor
, Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
792 &FontInfo
->ForegroundColor
,
793 &mEfiColors
[Sto
->Mode
->Attribute
& 0x0f],
794 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
797 if (Background
!= NULL
) {
798 CopyMem (&FontInfo
->BackgroundColor
, Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
801 &FontInfo
->BackgroundColor
,
802 &mEfiColors
[Sto
->Mode
->Attribute
>> 4],
803 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
807 Status
= HiiFont
->StringToImage (
809 EFI_HII_IGNORE_IF_NO_GLYPH
| EFI_HII_DIRECT_TO_SCREEN
,
823 SafeFreePool (FontInfo
);
824 gBS
->FreePool (Buffer
);
832 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*ForeGround
, OPTIONAL
833 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BackGround
, OPTIONAL
841 Prints a formatted unicode string to the default console
845 X - X coordinate to start printing
847 Y - Y coordinate to start printing
849 ForeGround - Foreground color
851 BackGround - Background color
855 ... - Print arguments
859 Length of string printed to the console
864 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
865 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
866 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*Sto
;
870 VA_START (Args
, Fmt
);
872 Handle
= gST
->ConsoleOutHandle
;
874 Status
= gBS
->HandleProtocol (
876 &gEfiGraphicsOutputProtocolGuid
,
877 (VOID
**)&GraphicsOutput
881 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
882 GraphicsOutput
= NULL
;
884 Status
= gBS
->HandleProtocol (
886 &gEfiUgaDrawProtocolGuid
,
890 if (EFI_ERROR (Status
)) {
894 Status
= gBS
->HandleProtocol (
896 &gEfiSimpleTextOutProtocolGuid
,
900 if (EFI_ERROR (Status
)) {
904 return _IPrint (GraphicsOutput
, UgaDraw
, Sto
, X
, Y
, ForeGround
, BackGround
, Fmt
, Args
);