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>
42 STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors
[16] = {
43 { 0x00, 0x00, 0x00, 0x00 },
44 { 0x98, 0x00, 0x00, 0x00 },
45 { 0x00, 0x98, 0x00, 0x00 },
46 { 0x98, 0x98, 0x00, 0x00 },
47 { 0x00, 0x00, 0x98, 0x00 },
48 { 0x98, 0x00, 0x98, 0x00 },
49 { 0x00, 0x98, 0x98, 0x00 },
50 { 0x98, 0x98, 0x98, 0x00 },
51 { 0x10, 0x10, 0x10, 0x00 },
52 { 0xff, 0x10, 0x10, 0x00 },
53 { 0x10, 0xff, 0x10, 0x00 },
54 { 0xff, 0xff, 0x10, 0x00 },
55 { 0x10, 0x10, 0xff, 0x00 },
56 { 0xf0, 0x10, 0xff, 0x00 },
57 { 0x10, 0xff, 0xff, 0x00 },
58 { 0xff, 0xff, 0xff, 0x00 }
63 GetGraphicsBitMapFromFV (
64 IN EFI_GUID
*FileNameGuid
,
72 Return the graphics image file named FileNameGuid into Image and return it's
73 size in ImageSize. All Firmware Volumes (FV) in the system are searched for the
78 FileNameGuid - File Name of graphics file in the FV(s).
80 Image - Pointer to pointer to return graphics image. If NULL, a
81 buffer will be allocated.
83 ImageSize - Size of the graphics Image in bytes. Zero if no image found.
88 EFI_SUCCESS - Image and ImageSize are valid.
89 EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size
90 EFI_NOT_FOUND - FileNameGuid not found
94 return GetGraphicsBitMapFromFVEx (NULL
, FileNameGuid
, Image
, ImageSize
);
98 GetGraphicsBitMapFromFVEx (
99 IN EFI_HANDLE ImageHandle
,
100 IN EFI_GUID
*FileNameGuid
,
108 Return the graphics image file named FileNameGuid into Image and return it's
109 size in ImageSize. All Firmware Volumes (FV) in the system are searched for the
114 ImageHandle - The driver image handle of the caller. The parameter is used to
115 optimize the loading of the image file so that the FV from which
116 the driver image is loaded will be tried first.
118 FileNameGuid - File Name of graphics file in the FV(s).
120 Image - Pointer to pointer to return graphics image. If NULL, a
121 buffer will be allocated.
123 ImageSize - Size of the graphics Image in bytes. Zero if no image found.
128 EFI_SUCCESS - Image and ImageSize are valid.
129 EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size
130 EFI_NOT_FOUND - FileNameGuid not found
134 return PiLibGetSectionFromCurrentFv (
147 IN UINTN BmpImageSize
,
148 IN OUT VOID
**GopBlt
,
149 IN OUT UINTN
*GopBltSize
,
150 OUT UINTN
*PixelHeight
,
151 OUT UINTN
*PixelWidth
157 Convert a *.BMP graphics image to a GOP/UGA blt buffer. If a NULL Blt buffer
158 is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt
159 buffer is passed in it will be used if it is big enough.
163 BmpImage - Pointer to BMP file
165 BmpImageSize - Number of bytes in BmpImage
167 GopBlt - Buffer containing GOP version of BmpImage.
169 GopBltSize - Size of GopBlt in bytes.
171 PixelHeight - Height of GopBlt/BmpImage in pixels
173 PixelWidth - Width of GopBlt/BmpImage in pixels
178 EFI_SUCCESS - GopBlt and GopBltSize are returned.
179 EFI_UNSUPPORTED - BmpImage is not a valid *.BMP image
180 EFI_BUFFER_TOO_SMALL - The passed in GopBlt buffer is not big enough.
181 GopBltSize will contain the required size.
182 EFI_OUT_OF_RESOURCES - No enough buffer to allocate
188 BMP_IMAGE_HEADER
*BmpHeader
;
189 BMP_COLOR_MAP
*BmpColorMap
;
190 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
;
191 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
199 BmpHeader
= (BMP_IMAGE_HEADER
*) BmpImage
;
200 if (BmpHeader
->CharB
!= 'B' || BmpHeader
->CharM
!= 'M') {
201 return EFI_UNSUPPORTED
;
204 if (BmpHeader
->CompressionType
!= 0) {
205 return EFI_UNSUPPORTED
;
209 // Calculate Color Map offset in the image.
212 BmpColorMap
= (BMP_COLOR_MAP
*) (Image
+ sizeof (BMP_IMAGE_HEADER
));
215 // Calculate graphics image data address in the image
217 Image
= ((UINT8
*) BmpImage
) + BmpHeader
->ImageOffset
;
220 BltBufferSize
= BmpHeader
->PixelWidth
* BmpHeader
->PixelHeight
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
222 if (*GopBlt
== NULL
) {
223 *GopBltSize
= BltBufferSize
;
224 *GopBlt
= AllocatePool (*GopBltSize
);
226 if (*GopBlt
== NULL
) {
227 return EFI_OUT_OF_RESOURCES
;
230 if (*GopBltSize
< BltBufferSize
) {
231 *GopBltSize
= BltBufferSize
;
232 return EFI_BUFFER_TOO_SMALL
;
236 *PixelWidth
= BmpHeader
->PixelWidth
;
237 *PixelHeight
= BmpHeader
->PixelHeight
;
240 // Convert image from BMP to Blt buffer format
243 for (Height
= 0; Height
< BmpHeader
->PixelHeight
; Height
++) {
244 Blt
= &BltBuffer
[(BmpHeader
->PixelHeight
- Height
- 1) * BmpHeader
->PixelWidth
];
245 for (Width
= 0; Width
< BmpHeader
->PixelWidth
; Width
++, Image
++, Blt
++) {
246 switch (BmpHeader
->BitPerPixel
) {
249 // Convert 1bit BMP to 24-bit color
251 for (Index
= 0; Index
< 8 && Width
< BmpHeader
->PixelWidth
; Index
++) {
252 Blt
->Red
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Red
;
253 Blt
->Green
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Green
;
254 Blt
->Blue
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Blue
;
265 // Convert BMP Palette to 24-bit color
267 Index
= (*Image
) >> 4;
268 Blt
->Red
= BmpColorMap
[Index
].Red
;
269 Blt
->Green
= BmpColorMap
[Index
].Green
;
270 Blt
->Blue
= BmpColorMap
[Index
].Blue
;
271 if (Width
< (BmpHeader
->PixelWidth
- 1)) {
274 Index
= (*Image
) & 0x0f;
275 Blt
->Red
= BmpColorMap
[Index
].Red
;
276 Blt
->Green
= BmpColorMap
[Index
].Green
;
277 Blt
->Blue
= BmpColorMap
[Index
].Blue
;
283 // Convert BMP Palette to 24-bit color
285 Blt
->Red
= BmpColorMap
[*Image
].Red
;
286 Blt
->Green
= BmpColorMap
[*Image
].Green
;
287 Blt
->Blue
= BmpColorMap
[*Image
].Blue
;
291 Blt
->Blue
= *Image
++;
292 Blt
->Green
= *Image
++;
298 gBS
->FreePool (*GopBlt
);
301 return EFI_UNSUPPORTED
;
307 ImageIndex
= (UINTN
) (Image
- ImageHeader
);
308 if ((ImageIndex
% 4) != 0) {
310 // Bmp Image starts each row on a 32-bit boundary!
312 Image
= Image
+ (4 - (ImageIndex
% 4));
327 Use Console Control Protocol to lock the Console In Spliter virtual handle.
328 This is the ConInHandle and ConIn handle in the EFI system table. All key
329 presses will be ignored until the Password is typed in. The only way to
330 disable the password is to type it in to a ConIn device.
333 Password - Password used to lock ConIn device
338 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo
340 EFI_UNSUPPORTED - Logo not found
345 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
347 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, (VOID
**) &ConsoleControl
);
348 if (EFI_ERROR (Status
)) {
349 return EFI_UNSUPPORTED
;
352 Status
= ConsoleControl
->LockStdIn (ConsoleControl
, Password
);
359 IN EFI_GUID
*LogoFile
365 Use Console Control to turn off UGA based Simple Text Out consoles from going
366 to the UGA device. Put up LogoFile on every UGA device that is a console
370 LogoFile - File name of logo to display on the center of the screen.
375 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo
377 EFI_UNSUPPORTED - Logo not found
381 return EnableQuietBootEx (LogoFile
, NULL
);
386 IN EFI_GUID
*LogoFile
,
387 IN EFI_HANDLE ImageHandle
393 Use Console Control to turn off GOP/UGA based Simple Text Out consoles from going
394 to the GOP/UGA device. Put up LogoFile on every GOP/UGA device that is a console
398 LogoFile - File name of logo to display on the center of the screen.
399 ImageHandle - The driver image handle of the caller. The parameter is used to
400 optimize the loading of the logo file so that the FV from which
401 the driver image is loaded will be tried first.
406 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo
408 EFI_UNSUPPORTED - Logo not found
413 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
414 EFI_OEM_BADGING_PROTOCOL
*Badging
;
423 EFI_BADGING_FORMAT Format
;
424 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute
;
429 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
430 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
433 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
435 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, (VOID
**)&ConsoleControl
);
436 if (EFI_ERROR (Status
)) {
437 return EFI_UNSUPPORTED
;
442 // Try to open GOP first
444 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiGraphicsOutputProtocolGuid
, (VOID
**)&GraphicsOutput
);
445 if (EFI_ERROR (Status
)) {
446 GraphicsOutput
= NULL
;
448 // Open GOP failed, try to open UGA
450 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiUgaDrawProtocolGuid
, (VOID
**)&UgaDraw
);
451 if (EFI_ERROR (Status
)) {
452 return EFI_UNSUPPORTED
;
457 Status
= gBS
->LocateProtocol (&gEfiOEMBadgingProtocolGuid
, NULL
, (VOID
**)&Badging
);
459 ConsoleControl
->SetMode (ConsoleControl
, EfiConsoleControlScreenGraphics
);
461 if (GraphicsOutput
!= NULL
) {
462 SizeOfX
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
463 SizeOfY
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
465 Status
= UgaDraw
->GetMode (UgaDraw
, &SizeOfX
, &SizeOfY
, &ColorDepth
, &RefreshRate
);
466 if (EFI_ERROR (Status
)) {
467 return EFI_UNSUPPORTED
;
476 if (Badging
!= NULL
) {
477 Status
= Badging
->GetImage (
487 if (EFI_ERROR (Status
)) {
492 // Currently only support BMP format
494 if (Format
!= EfiBadgingFormatBMP
) {
495 gBS
->FreePool (ImageData
);
499 Status
= GetGraphicsBitMapFromFVEx (ImageHandle
, LogoFile
, (VOID
**) &ImageData
, &ImageSize
);
500 if (EFI_ERROR (Status
)) {
501 return EFI_UNSUPPORTED
;
506 Attribute
= EfiBadgingDisplayAttributeCenter
;
510 Status
= ConvertBmpToGopBlt (
518 if (EFI_ERROR (Status
)) {
519 gBS
->FreePool (ImageData
);
520 if (Badging
== NULL
) {
528 case EfiBadgingDisplayAttributeLeftTop
:
533 case EfiBadgingDisplayAttributeCenterTop
:
534 DestX
= (SizeOfX
- Width
) / 2;
538 case EfiBadgingDisplayAttributeRightTop
:
539 DestX
= (SizeOfX
- Width
- CoordinateX
);
540 DestY
= CoordinateY
;;
543 case EfiBadgingDisplayAttributeCenterRight
:
544 DestX
= (SizeOfX
- Width
- CoordinateX
);
545 DestY
= (SizeOfY
- Height
) / 2;
548 case EfiBadgingDisplayAttributeRightBottom
:
549 DestX
= (SizeOfX
- Width
- CoordinateX
);
550 DestY
= (SizeOfY
- Height
- CoordinateY
);
553 case EfiBadgingDisplayAttributeCenterBottom
:
554 DestX
= (SizeOfX
- Width
) / 2;
555 DestY
= (SizeOfY
- Height
- CoordinateY
);
558 case EfiBadgingDisplayAttributeLeftBottom
:
560 DestY
= (SizeOfY
- Height
- CoordinateY
);
563 case EfiBadgingDisplayAttributeCenterLeft
:
565 DestY
= (SizeOfY
- Height
) / 2;
568 case EfiBadgingDisplayAttributeCenter
:
569 DestX
= (SizeOfX
- Width
) / 2;
570 DestY
= (SizeOfY
- Height
) / 2;
579 if ((DestX
>= 0) && (DestY
>= 0)) {
580 if (GraphicsOutput
!= NULL
) {
581 Status
= GraphicsOutput
->Blt (
591 Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
594 Status
= UgaDraw
->Blt (
596 (EFI_UGA_PIXEL
*) Blt
,
597 EfiUgaBltBufferToVideo
,
604 Width
* sizeof (EFI_UGA_PIXEL
)
609 gBS
->FreePool (ImageData
);
612 if (Badging
== NULL
) {
629 Use Console Control to turn on GOP/UGA based Simple Text Out consoles. The GOP/UGA
630 Simple Text Out screens will now be synced up with all non GOP/UGA output devices
638 EFI_SUCCESS - GOP/UGA devices are back in text mode and synced up.
639 EFI_UNSUPPORTED - Logo not found
644 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
646 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, (VOID
**) &ConsoleControl
);
647 if (EFI_ERROR (Status
)) {
648 return EFI_UNSUPPORTED
;
651 return ConsoleControl
->SetMode (ConsoleControl
, EfiConsoleControlScreenText
);
656 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
657 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
,
658 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*Sto
,
661 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Foreground
,
662 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Background
,
670 Display string worker for: Print, PrintAt, IPrint, IPrintAt
674 GraphicsOutput - Graphics output protocol interface
676 UgaDraw - UGA draw protocol interface
678 Sto - Simple text out protocol interface
680 X - X coordinate to start printing
682 Y - Y coordinate to start printing
684 Foreground - Foreground color
686 Background - Background color
690 args - Print arguments
694 EFI_SUCCESS - success
695 EFI_OUT_OF_RESOURCES - out of resources
702 CHAR16
*UnicodeWeight
;
703 UINT32 HorizontalResolution
;
704 UINT32 VerticalResolution
;
709 EFI_HII_FONT_PROTOCOL
*HiiFont
;
710 EFI_IMAGE_OUTPUT
*Blt
;
711 EFI_FONT_DISPLAY_INFO
*FontInfo
;
714 // For now, allocate an arbitrarily long buffer
716 Buffer
= AllocateZeroPool (0x10000);
717 if (Buffer
== NULL
) {
718 return EFI_OUT_OF_RESOURCES
;
721 if (GraphicsOutput
!= NULL
) {
722 HorizontalResolution
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
723 VerticalResolution
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
725 UgaDraw
->GetMode (UgaDraw
, &HorizontalResolution
, &VerticalResolution
, &ColorDepth
, &RefreshRate
);
727 ASSERT ((HorizontalResolution
!= 0) && (VerticalResolution
!=0));
731 ASSERT (GraphicsOutput
!= NULL
);
732 Status
= gBS
->LocateProtocol (&gEfiHiiFontProtocolGuid
, NULL
, (VOID
**) &HiiFont
);
733 if (EFI_ERROR (Status
)) {
737 UnicodeVSPrint (Buffer
, 0x10000, fmt
, args
);
739 UnicodeWeight
= (CHAR16
*) Buffer
;
741 for (Index
= 0; UnicodeWeight
[Index
] != 0; Index
++) {
742 if (UnicodeWeight
[Index
] == CHAR_BACKSPACE
||
743 UnicodeWeight
[Index
] == CHAR_LINEFEED
||
744 UnicodeWeight
[Index
] == CHAR_CARRIAGE_RETURN
) {
745 UnicodeWeight
[Index
] = 0;
749 BufferLen
= StrLen (Buffer
);
752 LineBufferLen
= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * HorizontalResolution
* EFI_GLYPH_HEIGHT
;
753 if (EFI_GLYPH_WIDTH
* EFI_GLYPH_HEIGHT
* sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * BufferLen
> LineBufferLen
) {
754 Status
= EFI_INVALID_PARAMETER
;
758 Blt
= (EFI_IMAGE_OUTPUT
*) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT
));
760 Status
= EFI_OUT_OF_RESOURCES
;
764 Blt
->Width
= (UINT16
) (HorizontalResolution
);
765 Blt
->Height
= (UINT16
) (VerticalResolution
);
766 Blt
->Image
.Screen
= GraphicsOutput
;
768 FontInfo
= (EFI_FONT_DISPLAY_INFO
*) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO
));
769 if (FontInfo
== NULL
) {
770 Status
= EFI_OUT_OF_RESOURCES
;
773 if (Foreground
!= NULL
) {
774 CopyMem (&FontInfo
->ForegroundColor
, Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
777 &FontInfo
->ForegroundColor
,
778 &mEfiColors
[Sto
->Mode
->Attribute
& 0x0f],
779 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
782 if (Background
!= NULL
) {
783 CopyMem (&FontInfo
->BackgroundColor
, Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
786 &FontInfo
->BackgroundColor
,
787 &mEfiColors
[Sto
->Mode
->Attribute
>> 4],
788 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
792 Status
= HiiFont
->StringToImage (
794 EFI_HII_IGNORE_IF_NO_GLYPH
| EFI_HII_DIRECT_TO_SCREEN
,
808 SafeFreePool (FontInfo
);
809 gBS
->FreePool (Buffer
);
817 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*ForeGround
, OPTIONAL
818 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BackGround
, OPTIONAL
826 Prints a formatted unicode string to the default console
830 X - X coordinate to start printing
832 Y - Y coordinate to start printing
834 ForeGround - Foreground color
836 BackGround - Background color
840 ... - Print arguments
844 Length of string printed to the console
849 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
850 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
851 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*Sto
;
855 VA_START (Args
, Fmt
);
857 Handle
= gST
->ConsoleOutHandle
;
859 Status
= gBS
->HandleProtocol (
861 &gEfiGraphicsOutputProtocolGuid
,
862 (VOID
**)&GraphicsOutput
866 if (EFI_ERROR (Status
)) {
867 GraphicsOutput
= NULL
;
869 Status
= gBS
->HandleProtocol (
871 &gEfiUgaDrawProtocolGuid
,
875 if (EFI_ERROR (Status
)) {
880 Status
= gBS
->HandleProtocol (
882 &gEfiSimpleTextOutProtocolGuid
,
886 if (EFI_ERROR (Status
)) {
890 return _IPrint (GraphicsOutput
, UgaDraw
, Sto
, X
, Y
, ForeGround
, BackGround
, Fmt
, Args
);