3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Support for Basic Graphics operations.
20 BugBug: Currently *.BMP files are supported. This will be replaced
21 when Tiano graphics format is supported.
27 // Include common header file for this module.
29 #include "CommonHeader.h"
32 GetGraphicsBitMapFromFV (
33 IN EFI_GUID
*FileNameGuid
,
41 Return the graphics image file named FileNameGuid into Image and return it's
42 size in ImageSize. All Firmware Volumes (FV) in the system are searched for the
47 FileNameGuid - File Name of graphics file in the FV(s).
49 Image - Pointer to pointer to return graphics image. If NULL, a
50 buffer will be allocated.
52 ImageSize - Size of the graphics Image in bytes. Zero if no image found.
57 EFI_SUCCESS - Image and ImageSize are valid.
58 EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size
59 EFI_NOT_FOUND - FileNameGuid not found
64 UINTN FvProtocolCount
;
65 EFI_HANDLE
*FvHandles
;
66 EFI_FIRMWARE_VOLUME_PROTOCOL
*Fv
;
68 UINT32 AuthenticationStatus
;
71 Status
= gBS
->LocateHandleBuffer (
73 &gEfiFirmwareVolumeProtocolGuid
,
78 if (EFI_ERROR (Status
)) {
82 for (Index
= 0; Index
< FvProtocolCount
; Index
++) {
83 Status
= gBS
->HandleProtocol (
85 &gEfiFirmwareVolumeProtocolGuid
,
90 // Assuming Image and ImageSize are correct on input.
92 Status
= Fv
->ReadSection (
101 if (!EFI_ERROR (Status
)) {
103 } else if (Status
== EFI_BUFFER_TOO_SMALL
) {
105 // ImageSize updated to needed size so return
107 return EFI_BUFFER_TOO_SMALL
;
111 return EFI_NOT_FOUND
;
118 IN UINTN BmpImageSize
,
119 IN OUT VOID
**GopBlt
,
120 IN OUT UINTN
*GopBltSize
,
121 OUT UINTN
*PixelHeight
,
122 OUT UINTN
*PixelWidth
128 Convert a *.BMP graphics image to a UGA blt buffer. If a NULL UgaBlt buffer
129 is passed in a UgaBlt buffer will be allocated by this routine. If a UgaBlt
130 buffer is passed in it will be used if it is big enough.
134 BmpImage - Pointer to BMP file
136 BmpImageSize - Number of bytes in BmpImage
138 UgaBlt - Buffer containing UGA version of BmpImage.
140 UgaBltSize - Size of UgaBlt in bytes.
142 PixelHeight - Height of UgaBlt/BmpImage in pixels
144 PixelWidth - Width of UgaBlt/BmpImage in pixels
149 EFI_SUCCESS - UgaBlt and UgaBltSize are returned.
150 EFI_UNSUPPORTED - BmpImage is not a valid *.BMP image
151 EFI_BUFFER_TOO_SMALL - The passed in UgaBlt buffer is not big enough.
152 UgaBltSize will contain the required size.
153 EFI_OUT_OF_RESOURCES - No enough buffer to allocate
159 BMP_IMAGE_HEADER
*BmpHeader
;
160 BMP_COLOR_MAP
*BmpColorMap
;
161 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
;
162 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
170 BmpHeader
= (BMP_IMAGE_HEADER
*) BmpImage
;
171 if (BmpHeader
->CharB
!= 'B' || BmpHeader
->CharM
!= 'M') {
172 return EFI_UNSUPPORTED
;
175 if (BmpHeader
->CompressionType
!= 0) {
176 return EFI_UNSUPPORTED
;
180 // Calculate Color Map offset in the image.
183 BmpColorMap
= (BMP_COLOR_MAP
*) (Image
+ sizeof (BMP_IMAGE_HEADER
));
186 // Calculate graphics image data address in the image
188 Image
= ((UINT8
*) BmpImage
) + BmpHeader
->ImageOffset
;
191 BltBufferSize
= BmpHeader
->PixelWidth
* BmpHeader
->PixelHeight
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
193 if (*GopBlt
== NULL
) {
194 *GopBltSize
= BltBufferSize
;
195 *GopBlt
= AllocatePool (*GopBltSize
);
197 if (*GopBlt
== NULL
) {
198 return EFI_OUT_OF_RESOURCES
;
201 if (*GopBltSize
< BltBufferSize
) {
202 *GopBltSize
= BltBufferSize
;
203 return EFI_BUFFER_TOO_SMALL
;
207 *PixelWidth
= BmpHeader
->PixelWidth
;
208 *PixelHeight
= BmpHeader
->PixelHeight
;
211 // Convert image from BMP to Blt buffer format
214 for (Height
= 0; Height
< BmpHeader
->PixelHeight
; Height
++) {
215 Blt
= &BltBuffer
[(BmpHeader
->PixelHeight
- Height
- 1) * BmpHeader
->PixelWidth
];
216 for (Width
= 0; Width
< BmpHeader
->PixelWidth
; Width
++, Image
++, Blt
++) {
217 switch (BmpHeader
->BitPerPixel
) {
220 // Convert 1bit BMP to 24-bit color
222 for (Index
= 0; Index
< 8 && Width
< BmpHeader
->PixelWidth
; Index
++) {
223 Blt
->Red
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Red
;
224 Blt
->Green
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Green
;
225 Blt
->Blue
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Blue
;
236 // Convert BMP Palette to 24-bit color
238 Index
= (*Image
) >> 4;
239 Blt
->Red
= BmpColorMap
[Index
].Red
;
240 Blt
->Green
= BmpColorMap
[Index
].Green
;
241 Blt
->Blue
= BmpColorMap
[Index
].Blue
;
242 if (Width
< (BmpHeader
->PixelWidth
- 1)) {
245 Index
= (*Image
) & 0x0f;
246 Blt
->Red
= BmpColorMap
[Index
].Red
;
247 Blt
->Green
= BmpColorMap
[Index
].Green
;
248 Blt
->Blue
= BmpColorMap
[Index
].Blue
;
254 // Convert BMP Palette to 24-bit color
256 Blt
->Red
= BmpColorMap
[*Image
].Red
;
257 Blt
->Green
= BmpColorMap
[*Image
].Green
;
258 Blt
->Blue
= BmpColorMap
[*Image
].Blue
;
262 Blt
->Blue
= *Image
++;
263 Blt
->Green
= *Image
++;
269 gBS
->FreePool (*GopBlt
);
272 return EFI_UNSUPPORTED
;
278 ImageIndex
= (UINTN
) (Image
- ImageHeader
);
279 if ((ImageIndex
% 4) != 0) {
281 // Bmp Image starts each row on a 32-bit boundary!
283 Image
= Image
+ (4 - (ImageIndex
% 4));
298 Use Console Control Protocol to lock the Console In Spliter virtual handle.
299 This is the ConInHandle and ConIn handle in the EFI system table. All key
300 presses will be ignored until the Password is typed in. The only way to
301 disable the password is to type it in to a ConIn device.
304 Password - Password used to lock ConIn device
309 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo
311 EFI_UNSUPPORTED - Logo not found
316 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
318 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, (VOID
**) &ConsoleControl
);
319 if (EFI_ERROR (Status
)) {
320 return EFI_UNSUPPORTED
;
323 Status
= ConsoleControl
->LockStdIn (ConsoleControl
, Password
);
330 IN EFI_GUID
*LogoFile
336 Use Console Control to turn off UGA based Simple Text Out consoles from going
337 to the UGA device. Put up LogoFile on every UGA device that is a console
341 LogoFile - File name of logo to display on the center of the screen.
346 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo
348 EFI_UNSUPPORTED - Logo not found
353 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
354 EFI_OEM_BADGING_PROTOCOL
*Badging
;
363 EFI_BADGING_FORMAT Format
;
364 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute
;
369 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
370 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
373 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
375 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, (VOID
**) &ConsoleControl
);
376 if (EFI_ERROR (Status
)) {
377 return EFI_UNSUPPORTED
;
382 // Try to open GOP first
384 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiGraphicsOutputProtocolGuid
, (VOID
**) &GraphicsOutput
);
385 if (EFI_ERROR(Status
)) {
386 GraphicsOutput
= NULL
;
388 // Open GOP failed, try to open UGA
390 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiUgaDrawProtocolGuid
, (VOID
**) &UgaDraw
);
391 if (EFI_ERROR (Status
)) {
392 return EFI_UNSUPPORTED
;
397 Status
= gBS
->LocateProtocol (&gEfiOEMBadgingProtocolGuid
, NULL
, (VOID
**) &Badging
);
399 ConsoleControl
->SetMode (ConsoleControl
, EfiConsoleControlScreenGraphics
);
401 if (GraphicsOutput
!= NULL
) {
402 SizeOfX
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
403 SizeOfY
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
405 Status
= UgaDraw
->GetMode (UgaDraw
, &SizeOfX
, &SizeOfY
, &ColorDepth
, &RefreshRate
);
406 if (EFI_ERROR (Status
)) {
407 return EFI_UNSUPPORTED
;
416 if (Badging
!= NULL
) {
417 Status
= Badging
->GetImage (
427 if (EFI_ERROR (Status
)) {
432 // Currently only support BMP format
434 if (Format
!= EfiBadgingFormatBMP
) {
435 gBS
->FreePool (ImageData
);
439 Status
= GetGraphicsBitMapFromFV (LogoFile
, (VOID
**) &ImageData
, &ImageSize
);
440 if (EFI_ERROR (Status
)) {
441 return EFI_UNSUPPORTED
;
446 Attribute
= EfiBadgingDisplayAttributeCenter
;
451 Status
= ConvertBmpToGopBlt (
459 if (EFI_ERROR (Status
)) {
460 gBS
->FreePool (ImageData
);
461 if (Badging
== NULL
) {
469 case EfiBadgingDisplayAttributeLeftTop
:
474 case EfiBadgingDisplayAttributeCenterTop
:
475 DestX
= (SizeOfX
- Width
) / 2;
479 case EfiBadgingDisplayAttributeRightTop
:
480 DestX
= (SizeOfX
- Width
- CoordinateX
);
481 DestY
= CoordinateY
;;
484 case EfiBadgingDisplayAttributeCenterRight
:
485 DestX
= (SizeOfX
- Width
- CoordinateX
);
486 DestY
= (SizeOfY
- Height
) / 2;
489 case EfiBadgingDisplayAttributeRightBottom
:
490 DestX
= (SizeOfX
- Width
- CoordinateX
);
491 DestY
= (SizeOfY
- Height
- CoordinateY
);
494 case EfiBadgingDisplayAttributeCenterBottom
:
495 DestX
= (SizeOfX
- Width
) / 2;
496 DestY
= (SizeOfY
- Height
- CoordinateY
);
499 case EfiBadgingDisplayAttributeLeftBottom
:
501 DestY
= (SizeOfY
- Height
- CoordinateY
);
504 case EfiBadgingDisplayAttributeCenterLeft
:
506 DestY
= (SizeOfY
- Height
) / 2;
509 case EfiBadgingDisplayAttributeCenter
:
510 DestX
= (SizeOfX
- Width
) / 2;
511 DestY
= (SizeOfY
- Height
) / 2;
520 if ((DestX
>= 0) && (DestY
>= 0)) {
521 if (GraphicsOutput
!= NULL
) {
522 Status
= GraphicsOutput
->Blt (
532 Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
535 Status
= UgaDraw
->Blt (
537 (EFI_UGA_PIXEL
*) Blt
,
538 EfiUgaBltBufferToVideo
,
545 Width
* sizeof (EFI_UGA_PIXEL
)
550 gBS
->FreePool (ImageData
);
553 if (Badging
== NULL
) {
570 Use Console Control to turn on UGA based Simple Text Out consoles. The UGA
571 Simple Text Out screens will now be synced up with all non UGA output devices
579 EFI_SUCCESS - UGA devices are back in text mode and synced up.
580 EFI_UNSUPPORTED - Logo not found
585 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
587 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, (VOID
**) &ConsoleControl
);
588 if (EFI_ERROR (Status
)) {
589 return EFI_UNSUPPORTED
;
592 return ConsoleControl
->SetMode (ConsoleControl
, EfiConsoleControlScreenText
);
595 static EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors
[16] = {
596 { 0x00, 0x00, 0x00, 0x00 },
597 { 0x98, 0x00, 0x00, 0x00 },
598 { 0x00, 0x98, 0x00, 0x00 },
599 { 0x98, 0x98, 0x00, 0x00 },
600 { 0x00, 0x00, 0x98, 0x00 },
601 { 0x98, 0x00, 0x98, 0x00 },
602 { 0x00, 0x98, 0x98, 0x00 },
603 { 0x98, 0x98, 0x98, 0x00 },
604 { 0x10, 0x10, 0x10, 0x00 },
605 { 0xff, 0x10, 0x10, 0x00 },
606 { 0x10, 0xff, 0x10, 0x00 },
607 { 0xff, 0xff, 0x10, 0x00 },
608 { 0x10, 0x10, 0xff, 0x00 },
609 { 0xf0, 0x10, 0xff, 0x00 },
610 { 0x10, 0xff, 0xff, 0x00 },
611 { 0xff, 0xff, 0xff, 0x00 }
617 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
618 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
,
619 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*Sto
,
622 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Foreground
,
623 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Background
,
631 Display string worker for: Print, PrintAt, IPrint, IPrintAt
635 GraphicsOutput - Graphics output protocol interface
637 UgaDraw - UGA draw protocol interface
639 Sto - Simple text out protocol interface
641 X - X coordinate to start printing
643 Y - Y coordinate to start printing
645 Foreground - Foreground color
647 Background - Background color
651 args - Print arguments
655 EFI_SUCCESS - success
656 EFI_OUT_OF_RESOURCES - out of resources
666 CHAR16
*UnicodeWeight
;
667 EFI_NARROW_GLYPH
*Glyph
;
668 EFI_HII_PROTOCOL
*Hii
;
669 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*LineBuffer
;
670 UINT32 HorizontalResolution
;
671 UINT32 VerticalResolution
;
674 UINTN BufferGlyphWidth
;
679 // For now, allocate an arbitrarily long buffer
681 Buffer
= AllocateZeroPool (0x10000);
682 if (Buffer
== NULL
) {
683 return EFI_OUT_OF_RESOURCES
;
686 if (GraphicsOutput
!= NULL
) {
687 HorizontalResolution
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
688 VerticalResolution
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
691 // Get the current mode information from the UGA Draw Protocol
693 UgaDraw
->GetMode (UgaDraw
, &HorizontalResolution
, &VerticalResolution
, &ColorDepth
, &RefreshRate
);
696 LineBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * HorizontalResolution
* GLYPH_WIDTH
* GLYPH_HEIGHT
);
697 if (LineBuffer
== NULL
) {
698 gBS
->FreePool (Buffer
);
699 return EFI_OUT_OF_RESOURCES
;
702 Status
= gBS
->LocateProtocol (&gEfiHiiProtocolGuid
, NULL
, (VOID
**) &Hii
);
703 if (EFI_ERROR (Status
)) {
707 UnicodeVSPrint (Buffer
, 0x10000, fmt
, args
);
709 UnicodeWeight
= (CHAR16
*) Buffer
;
711 for (Index
= 0; UnicodeWeight
[Index
] != 0; Index
++) {
712 if (UnicodeWeight
[Index
] == CHAR_BACKSPACE
||
713 UnicodeWeight
[Index
] == CHAR_LINEFEED
||
714 UnicodeWeight
[Index
] == CHAR_CARRIAGE_RETURN
) {
715 UnicodeWeight
[Index
] = 0;
719 for (Index
= 0; Index
< StrLen (Buffer
); Index
++) {
720 StringIndex
= (UINT16
) Index
;
721 Status
= Hii
->GetGlyph (Hii
, UnicodeWeight
, &StringIndex
, (UINT8
**) &Glyph
, &GlyphWidth
, &GlyphStatus
);
722 if (EFI_ERROR (Status
)) {
726 if (Foreground
== NULL
|| Background
== NULL
) {
727 Status
= Hii
->GlyphToBlt (
730 mEfiColors
[Sto
->Mode
->Attribute
& 0x0f],
731 mEfiColors
[Sto
->Mode
->Attribute
>> 4],
735 &LineBuffer
[Index
* GLYPH_WIDTH
]
738 Status
= Hii
->GlyphToBlt (
746 &LineBuffer
[Index
* GLYPH_WIDTH
]
752 // Blt a character to the screen
754 BufferGlyphWidth
= GLYPH_WIDTH
* StrLen (Buffer
);
755 if (GraphicsOutput
!= NULL
) {
756 Status
= GraphicsOutput
->Blt (
766 BufferGlyphWidth
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
769 Status
= UgaDraw
->Blt (
771 (EFI_UGA_PIXEL
*) (UINTN
) LineBuffer
,
772 EfiUgaBltBufferToVideo
,
779 BufferGlyphWidth
* sizeof (EFI_UGA_PIXEL
)
784 gBS
->FreePool (LineBuffer
);
785 gBS
->FreePool (Buffer
);
794 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*ForeGround
, OPTIONAL
795 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BackGround
, OPTIONAL
803 Prints a formatted unicode string to the default console
807 X - X coordinate to start printing
809 Y - Y coordinate to start printing
811 ForeGround - Foreground color
813 BackGround - Background color
817 ... - Print arguments
821 Length of string printed to the console
827 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
828 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
829 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*Sto
;
833 VA_START (Args
, Fmt
);
837 Handle
= gST
->ConsoleOutHandle
;
839 Status
= gBS
->HandleProtocol (
841 &gEfiGraphicsOutputProtocolGuid
,
842 (VOID
**) &GraphicsOutput
845 if (EFI_ERROR (Status
)) {
846 GraphicsOutput
= NULL
;
848 Status
= gBS
->HandleProtocol (
850 &gEfiUgaDrawProtocolGuid
,
854 if (EFI_ERROR (Status
)) {
859 Status
= gBS
->HandleProtocol (
861 &gEfiSimpleTextOutProtocolGuid
,
865 if (EFI_ERROR (Status
)) {
869 return _IPrint (GraphicsOutput
, UgaDraw
, Sto
, X
, Y
, ForeGround
, BackGround
, Fmt
, Args
);