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.
20 // Include common header file for this module.
22 #include "CommonHeader.h"
25 GetGraphicsBitMapFromFV (
26 IN EFI_GUID
*FileNameGuid
,
34 Return the graphics image file named FileNameGuid into Image and return it's
35 size in ImageSize. All Firmware Volumes (FV) in the system are searched for the
40 FileNameGuid - File Name of graphics file in the FV(s).
42 Image - Pointer to pointer to return graphics image. If NULL, a
43 buffer will be allocated.
45 ImageSize - Size of the graphics Image in bytes. Zero if no image found.
50 EFI_SUCCESS - Image and ImageSize are valid.
51 EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size
52 EFI_NOT_FOUND - FileNameGuid not found
57 UINTN FvProtocolCount
;
58 EFI_HANDLE
*FvHandles
;
59 EFI_FIRMWARE_VOLUME2_PROTOCOL
*Fv
;
61 UINT32 AuthenticationStatus
;
64 Status
= gBS
->LocateHandleBuffer (
66 &gEfiFirmwareVolume2ProtocolGuid
,
71 if (EFI_ERROR (Status
)) {
75 for (Index
= 0; Index
< FvProtocolCount
; Index
++) {
76 Status
= gBS
->HandleProtocol (
78 &gEfiFirmwareVolume2ProtocolGuid
,
83 // Assuming Image and ImageSize are correct on input.
85 Status
= Fv
->ReadSection (
94 if (!EFI_ERROR (Status
)) {
96 } else if (Status
== EFI_BUFFER_TOO_SMALL
) {
98 // ImageSize updated to needed size so return
100 return EFI_BUFFER_TOO_SMALL
;
104 return EFI_NOT_FOUND
;
111 IN UINTN BmpImageSize
,
112 IN OUT VOID
**GopBlt
,
113 IN OUT UINTN
*GopBltSize
,
114 OUT UINTN
*PixelHeight
,
115 OUT UINTN
*PixelWidth
121 Convert a *.BMP graphics image to a UGA blt buffer. If a NULL UgaBlt buffer
122 is passed in a UgaBlt buffer will be allocated by this routine. If a UgaBlt
123 buffer is passed in it will be used if it is big enough.
127 BmpImage - Pointer to BMP file
129 BmpImageSize - Number of bytes in BmpImage
131 UgaBlt - Buffer containing UGA version of BmpImage.
133 UgaBltSize - Size of UgaBlt in bytes.
135 PixelHeight - Height of UgaBlt/BmpImage in pixels
137 PixelWidth - Width of UgaBlt/BmpImage in pixels
142 EFI_SUCCESS - UgaBlt and UgaBltSize are returned.
143 EFI_UNSUPPORTED - BmpImage is not a valid *.BMP image
144 EFI_BUFFER_TOO_SMALL - The passed in UgaBlt buffer is not big enough.
145 UgaBltSize will contain the required size.
146 EFI_OUT_OF_RESOURCES - No enough buffer to allocate
152 BMP_IMAGE_HEADER
*BmpHeader
;
153 BMP_COLOR_MAP
*BmpColorMap
;
154 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
;
155 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
163 BmpHeader
= (BMP_IMAGE_HEADER
*) BmpImage
;
164 if (BmpHeader
->CharB
!= 'B' || BmpHeader
->CharM
!= 'M') {
165 return EFI_UNSUPPORTED
;
168 if (BmpHeader
->CompressionType
!= 0) {
169 return EFI_UNSUPPORTED
;
173 // Calculate Color Map offset in the image.
176 BmpColorMap
= (BMP_COLOR_MAP
*) (Image
+ sizeof (BMP_IMAGE_HEADER
));
179 // Calculate graphics image data address in the image
181 Image
= ((UINT8
*) BmpImage
) + BmpHeader
->ImageOffset
;
184 BltBufferSize
= BmpHeader
->PixelWidth
* BmpHeader
->PixelHeight
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
186 if (*GopBlt
== NULL
) {
187 *GopBltSize
= BltBufferSize
;
188 *GopBlt
= AllocatePool (*GopBltSize
);
190 if (*GopBlt
== NULL
) {
191 return EFI_OUT_OF_RESOURCES
;
194 if (*GopBltSize
< BltBufferSize
) {
195 *GopBltSize
= BltBufferSize
;
196 return EFI_BUFFER_TOO_SMALL
;
200 *PixelWidth
= BmpHeader
->PixelWidth
;
201 *PixelHeight
= BmpHeader
->PixelHeight
;
204 // Convert image from BMP to Blt buffer format
207 for (Height
= 0; Height
< BmpHeader
->PixelHeight
; Height
++) {
208 Blt
= &BltBuffer
[(BmpHeader
->PixelHeight
- Height
- 1) * BmpHeader
->PixelWidth
];
209 for (Width
= 0; Width
< BmpHeader
->PixelWidth
; Width
++, Image
++, Blt
++) {
210 switch (BmpHeader
->BitPerPixel
) {
213 // Convert 1bit BMP to 24-bit color
215 for (Index
= 0; Index
< 8 && Width
< BmpHeader
->PixelWidth
; Index
++) {
216 Blt
->Red
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Red
;
217 Blt
->Green
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Green
;
218 Blt
->Blue
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Blue
;
229 // Convert BMP Palette to 24-bit color
231 Index
= (*Image
) >> 4;
232 Blt
->Red
= BmpColorMap
[Index
].Red
;
233 Blt
->Green
= BmpColorMap
[Index
].Green
;
234 Blt
->Blue
= BmpColorMap
[Index
].Blue
;
235 if (Width
< (BmpHeader
->PixelWidth
- 1)) {
238 Index
= (*Image
) & 0x0f;
239 Blt
->Red
= BmpColorMap
[Index
].Red
;
240 Blt
->Green
= BmpColorMap
[Index
].Green
;
241 Blt
->Blue
= BmpColorMap
[Index
].Blue
;
247 // Convert BMP Palette to 24-bit color
249 Blt
->Red
= BmpColorMap
[*Image
].Red
;
250 Blt
->Green
= BmpColorMap
[*Image
].Green
;
251 Blt
->Blue
= BmpColorMap
[*Image
].Blue
;
255 Blt
->Blue
= *Image
++;
256 Blt
->Green
= *Image
++;
262 gBS
->FreePool (*GopBlt
);
265 return EFI_UNSUPPORTED
;
271 ImageIndex
= (UINTN
) (Image
- ImageHeader
);
272 if ((ImageIndex
% 4) != 0) {
274 // Bmp Image starts each row on a 32-bit boundary!
276 Image
= Image
+ (4 - (ImageIndex
% 4));
291 Use Console Control Protocol to lock the Console In Spliter virtual handle.
292 This is the ConInHandle and ConIn handle in the EFI system table. All key
293 presses will be ignored until the Password is typed in. The only way to
294 disable the password is to type it in to a ConIn device.
297 Password - Password used to lock ConIn device
302 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo
304 EFI_UNSUPPORTED - Logo not found
309 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
311 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, (VOID
**) &ConsoleControl
);
312 if (EFI_ERROR (Status
)) {
313 return EFI_UNSUPPORTED
;
316 Status
= ConsoleControl
->LockStdIn (ConsoleControl
, Password
);
323 IN EFI_GUID
*LogoFile
329 Use Console Control to turn off UGA based Simple Text Out consoles from going
330 to the UGA device. Put up LogoFile on every UGA device that is a console
334 LogoFile - File name of logo to display on the center of the screen.
339 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo
341 EFI_UNSUPPORTED - Logo not found
346 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
347 EFI_OEM_BADGING_PROTOCOL
*Badging
;
356 EFI_BADGING_FORMAT Format
;
357 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute
;
362 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
363 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
366 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
368 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, (VOID
**) &ConsoleControl
);
369 if (EFI_ERROR (Status
)) {
370 return EFI_UNSUPPORTED
;
375 // Try to open GOP first
377 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiGraphicsOutputProtocolGuid
, (VOID
**) &GraphicsOutput
);
378 if (EFI_ERROR(Status
)) {
379 GraphicsOutput
= NULL
;
381 // Open GOP failed, try to open UGA
383 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiUgaDrawProtocolGuid
, (VOID
**) &UgaDraw
);
384 if (EFI_ERROR (Status
)) {
385 return EFI_UNSUPPORTED
;
390 Status
= gBS
->LocateProtocol (&gEfiOEMBadgingProtocolGuid
, NULL
, (VOID
**) &Badging
);
392 ConsoleControl
->SetMode (ConsoleControl
, EfiConsoleControlScreenGraphics
);
394 if (GraphicsOutput
!= NULL
) {
395 SizeOfX
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
396 SizeOfY
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
398 Status
= UgaDraw
->GetMode (UgaDraw
, &SizeOfX
, &SizeOfY
, &ColorDepth
, &RefreshRate
);
399 if (EFI_ERROR (Status
)) {
400 return EFI_UNSUPPORTED
;
409 if (Badging
!= NULL
) {
410 Status
= Badging
->GetImage (
420 if (EFI_ERROR (Status
)) {
425 // Currently only support BMP format
427 if (Format
!= EfiBadgingFormatBMP
) {
428 gBS
->FreePool (ImageData
);
432 Status
= GetGraphicsBitMapFromFV (LogoFile
, (VOID
**) &ImageData
, &ImageSize
);
433 if (EFI_ERROR (Status
)) {
434 return EFI_UNSUPPORTED
;
439 Attribute
= EfiBadgingDisplayAttributeCenter
;
444 Status
= ConvertBmpToGopBlt (
452 if (EFI_ERROR (Status
)) {
453 gBS
->FreePool (ImageData
);
454 if (Badging
== NULL
) {
462 case EfiBadgingDisplayAttributeLeftTop
:
467 case EfiBadgingDisplayAttributeCenterTop
:
468 DestX
= (SizeOfX
- Width
) / 2;
472 case EfiBadgingDisplayAttributeRightTop
:
473 DestX
= (SizeOfX
- Width
- CoordinateX
);
474 DestY
= CoordinateY
;;
477 case EfiBadgingDisplayAttributeCenterRight
:
478 DestX
= (SizeOfX
- Width
- CoordinateX
);
479 DestY
= (SizeOfY
- Height
) / 2;
482 case EfiBadgingDisplayAttributeRightBottom
:
483 DestX
= (SizeOfX
- Width
- CoordinateX
);
484 DestY
= (SizeOfY
- Height
- CoordinateY
);
487 case EfiBadgingDisplayAttributeCenterBottom
:
488 DestX
= (SizeOfX
- Width
) / 2;
489 DestY
= (SizeOfY
- Height
- CoordinateY
);
492 case EfiBadgingDisplayAttributeLeftBottom
:
494 DestY
= (SizeOfY
- Height
- CoordinateY
);
497 case EfiBadgingDisplayAttributeCenterLeft
:
499 DestY
= (SizeOfY
- Height
) / 2;
502 case EfiBadgingDisplayAttributeCenter
:
503 DestX
= (SizeOfX
- Width
) / 2;
504 DestY
= (SizeOfY
- Height
) / 2;
513 if ((DestX
>= 0) && (DestY
>= 0)) {
514 if (GraphicsOutput
!= NULL
) {
515 Status
= GraphicsOutput
->Blt (
525 Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
528 Status
= UgaDraw
->Blt (
530 (EFI_UGA_PIXEL
*) Blt
,
531 EfiUgaBltBufferToVideo
,
538 Width
* sizeof (EFI_UGA_PIXEL
)
543 gBS
->FreePool (ImageData
);
546 if (Badging
== NULL
) {
563 Use Console Control to turn on UGA based Simple Text Out consoles. The UGA
564 Simple Text Out screens will now be synced up with all non UGA output devices
572 EFI_SUCCESS - UGA devices are back in text mode and synced up.
573 EFI_UNSUPPORTED - Logo not found
578 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
580 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, (VOID
**) &ConsoleControl
);
581 if (EFI_ERROR (Status
)) {
582 return EFI_UNSUPPORTED
;
585 return ConsoleControl
->SetMode (ConsoleControl
, EfiConsoleControlScreenText
);
588 static EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors
[16] = {
589 { 0x00, 0x00, 0x00, 0x00 },
590 { 0x98, 0x00, 0x00, 0x00 },
591 { 0x00, 0x98, 0x00, 0x00 },
592 { 0x98, 0x98, 0x00, 0x00 },
593 { 0x00, 0x00, 0x98, 0x00 },
594 { 0x98, 0x00, 0x98, 0x00 },
595 { 0x00, 0x98, 0x98, 0x00 },
596 { 0x98, 0x98, 0x98, 0x00 },
597 { 0x10, 0x10, 0x10, 0x00 },
598 { 0xff, 0x10, 0x10, 0x00 },
599 { 0x10, 0xff, 0x10, 0x00 },
600 { 0xff, 0xff, 0x10, 0x00 },
601 { 0x10, 0x10, 0xff, 0x00 },
602 { 0xf0, 0x10, 0xff, 0x00 },
603 { 0x10, 0xff, 0xff, 0x00 },
604 { 0xff, 0xff, 0xff, 0x00 }
610 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
611 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
,
612 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*Sto
,
615 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Foreground
,
616 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Background
,
624 Display string worker for: Print, PrintAt, IPrint, IPrintAt
628 GraphicsOutput - Graphics output protocol interface
630 UgaDraw - UGA draw protocol interface
632 Sto - Simple text out protocol interface
634 X - X coordinate to start printing
636 Y - Y coordinate to start printing
638 Foreground - Foreground color
640 Background - Background color
644 args - Print arguments
648 EFI_SUCCESS - success
649 EFI_OUT_OF_RESOURCES - out of resources
659 CHAR16
*UnicodeWeight
;
660 EFI_NARROW_GLYPH
*Glyph
;
661 EFI_HII_PROTOCOL
*Hii
;
662 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*LineBuffer
;
663 UINT32 HorizontalResolution
;
664 UINT32 VerticalResolution
;
667 UINTN BufferGlyphWidth
;
672 // For now, allocate an arbitrarily long buffer
674 Buffer
= AllocateZeroPool (0x10000);
675 if (Buffer
== NULL
) {
676 return EFI_OUT_OF_RESOURCES
;
679 if (GraphicsOutput
!= NULL
) {
680 HorizontalResolution
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
681 VerticalResolution
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
684 // Get the current mode information from the UGA Draw Protocol
686 UgaDraw
->GetMode (UgaDraw
, &HorizontalResolution
, &VerticalResolution
, &ColorDepth
, &RefreshRate
);
689 LineBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * HorizontalResolution
* GLYPH_WIDTH
* GLYPH_HEIGHT
);
690 if (LineBuffer
== NULL
) {
691 gBS
->FreePool (Buffer
);
692 return EFI_OUT_OF_RESOURCES
;
695 Status
= gBS
->LocateProtocol (&gEfiHiiProtocolGuid
, NULL
, (VOID
**) &Hii
);
696 if (EFI_ERROR (Status
)) {
700 UnicodeVSPrint (Buffer
, 0x10000, fmt
, args
);
702 UnicodeWeight
= (CHAR16
*) Buffer
;
704 for (Index
= 0; UnicodeWeight
[Index
] != 0; Index
++) {
705 if (UnicodeWeight
[Index
] == CHAR_BACKSPACE
||
706 UnicodeWeight
[Index
] == CHAR_LINEFEED
||
707 UnicodeWeight
[Index
] == CHAR_CARRIAGE_RETURN
) {
708 UnicodeWeight
[Index
] = 0;
712 for (Index
= 0; Index
< StrLen (Buffer
); Index
++) {
713 StringIndex
= (UINT16
) Index
;
714 Status
= Hii
->GetGlyph (Hii
, UnicodeWeight
, &StringIndex
, (UINT8
**) &Glyph
, &GlyphWidth
, &GlyphStatus
);
715 if (EFI_ERROR (Status
)) {
719 if (Foreground
== NULL
|| Background
== NULL
) {
720 Status
= Hii
->GlyphToBlt (
723 mEfiColors
[Sto
->Mode
->Attribute
& 0x0f],
724 mEfiColors
[Sto
->Mode
->Attribute
>> 4],
728 &LineBuffer
[Index
* GLYPH_WIDTH
]
731 Status
= Hii
->GlyphToBlt (
739 &LineBuffer
[Index
* GLYPH_WIDTH
]
745 // Blt a character to the screen
747 BufferGlyphWidth
= GLYPH_WIDTH
* StrLen (Buffer
);
748 if (GraphicsOutput
!= NULL
) {
749 Status
= GraphicsOutput
->Blt (
759 BufferGlyphWidth
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
762 Status
= UgaDraw
->Blt (
764 (EFI_UGA_PIXEL
*) (UINTN
) LineBuffer
,
765 EfiUgaBltBufferToVideo
,
772 BufferGlyphWidth
* sizeof (EFI_UGA_PIXEL
)
777 gBS
->FreePool (LineBuffer
);
778 gBS
->FreePool (Buffer
);
787 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*ForeGround
, OPTIONAL
788 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BackGround
, OPTIONAL
796 Prints a formatted unicode string to the default console
800 X - X coordinate to start printing
802 Y - Y coordinate to start printing
804 ForeGround - Foreground color
806 BackGround - Background color
810 ... - Print arguments
814 Length of string printed to the console
820 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
821 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
822 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*Sto
;
826 VA_START (Args
, Fmt
);
830 Handle
= gST
->ConsoleOutHandle
;
832 Status
= gBS
->HandleProtocol (
834 &gEfiGraphicsOutputProtocolGuid
,
835 (VOID
**) &GraphicsOutput
838 if (EFI_ERROR (Status
)) {
839 GraphicsOutput
= NULL
;
841 Status
= gBS
->HandleProtocol (
843 &gEfiUgaDrawProtocolGuid
,
847 if (EFI_ERROR (Status
)) {
852 Status
= gBS
->HandleProtocol (
854 &gEfiSimpleTextOutProtocolGuid
,
858 if (EFI_ERROR (Status
)) {
862 return _IPrint (GraphicsOutput
, UgaDraw
, Sto
, X
, Y
, ForeGround
, BackGround
, Fmt
, Args
);