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.
26 GetGraphicsBitMapFromFV (
27 IN EFI_GUID
*FileNameGuid
,
35 Return the graphics image file named FileNameGuid into Image and return it's
36 size in ImageSize. All Firmware Volumes (FV) in the system are searched for the
41 FileNameGuid - File Name of graphics file in the FV(s).
43 Image - Pointer to pointer to return graphics image. If NULL, a
44 buffer will be allocated.
46 ImageSize - Size of the graphics Image in bytes. Zero if no image found.
51 EFI_SUCCESS - Image and ImageSize are valid.
52 EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size
53 EFI_NOT_FOUND - FileNameGuid not found
58 UINTN FvProtocolCount
;
59 EFI_HANDLE
*FvHandles
;
60 EFI_FIRMWARE_VOLUME_PROTOCOL
*Fv
;
62 UINT32 AuthenticationStatus
;
65 Status
= gBS
->LocateHandleBuffer (
67 &gEfiFirmwareVolumeProtocolGuid
,
72 if (EFI_ERROR (Status
)) {
76 for (Index
= 0; Index
< FvProtocolCount
; Index
++) {
77 Status
= gBS
->HandleProtocol (
79 &gEfiFirmwareVolumeProtocolGuid
,
84 // Assuming Image and ImageSize are correct on input.
86 Status
= Fv
->ReadSection (
88 &gEfiDefaultBmpLogoGuid
,
95 if (!EFI_ERROR (Status
)) {
97 } else if (Status
== EFI_BUFFER_TOO_SMALL
) {
99 // ImageSize updated to needed size so return
101 return EFI_BUFFER_TOO_SMALL
;
105 return EFI_NOT_FOUND
;
112 IN UINTN BmpImageSize
,
113 IN OUT VOID
**UgaBlt
,
114 IN OUT UINTN
*UgaBltSize
,
115 OUT UINTN
*PixelHeight
,
116 OUT UINTN
*PixelWidth
122 Convert a *.BMP graphics image to a UGA blt buffer. If a NULL UgaBlt buffer
123 is passed in a UgaBlt buffer will be allocated by this routine. If a UgaBlt
124 buffer is passed in it will be used if it is big enough.
128 BmpImage - Pointer to BMP file
130 BmpImageSize - Number of bytes in BmpImage
132 UgaBlt - Buffer containing UGA version of BmpImage.
134 UgaBltSize - Size of UgaBlt in bytes.
136 PixelHeight - Height of UgaBlt/BmpImage in pixels
138 PixelWidth - Width of UgaBlt/BmpImage in pixels
143 EFI_SUCCESS - UgaBlt and UgaBltSize are returned.
144 EFI_UNSUPPORTED - BmpImage is not a valid *.BMP image
145 EFI_BUFFER_TOO_SMALL - The passed in UgaBlt buffer is not big enough.
146 UgaBltSize will contain the required size.
147 EFI_OUT_OF_RESOURCES - No enough buffer to allocate
153 BMP_IMAGE_HEADER
*BmpHeader
;
154 BMP_COLOR_MAP
*BmpColorMap
;
155 EFI_UGA_PIXEL
*BltBuffer
;
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_UGA_PIXEL
);
185 if (*UgaBlt
== NULL
) {
186 *UgaBltSize
= BltBufferSize
;
187 *UgaBlt
= AllocatePool (*UgaBltSize
);
188 if (*UgaBlt
== NULL
) {
189 return EFI_OUT_OF_RESOURCES
;
192 if (*UgaBltSize
< BltBufferSize
) {
193 *UgaBltSize
= BltBufferSize
;
194 return EFI_BUFFER_TOO_SMALL
;
198 *PixelWidth
= BmpHeader
->PixelWidth
;
199 *PixelHeight
= BmpHeader
->PixelHeight
;
202 // Convert image from BMP to Blt buffer format
205 for (Height
= 0; Height
< BmpHeader
->PixelHeight
; Height
++) {
206 Blt
= &BltBuffer
[(BmpHeader
->PixelHeight
- Height
- 1) * BmpHeader
->PixelWidth
];
207 for (Width
= 0; Width
< BmpHeader
->PixelWidth
; Width
++, Image
++, Blt
++) {
208 switch (BmpHeader
->BitPerPixel
) {
211 // Convert 1bit BMP to 24-bit color
213 for (Index
= 0; Index
< 8 && Width
< BmpHeader
->PixelWidth
; Index
++) {
214 Blt
->Red
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Red
;
215 Blt
->Green
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Green
;
216 Blt
->Blue
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Blue
;
227 // Convert BMP Palette to 24-bit color
229 Index
= (*Image
) >> 4;
230 Blt
->Red
= BmpColorMap
[Index
].Red
;
231 Blt
->Green
= BmpColorMap
[Index
].Green
;
232 Blt
->Blue
= BmpColorMap
[Index
].Blue
;
233 if (Width
< (BmpHeader
->PixelWidth
- 1)) {
236 Index
= (*Image
) & 0x0f;
237 Blt
->Red
= BmpColorMap
[Index
].Red
;
238 Blt
->Green
= BmpColorMap
[Index
].Green
;
239 Blt
->Blue
= BmpColorMap
[Index
].Blue
;
245 // Convert BMP Palette to 24-bit color
247 Blt
->Red
= BmpColorMap
[*Image
].Red
;
248 Blt
->Green
= BmpColorMap
[*Image
].Green
;
249 Blt
->Blue
= BmpColorMap
[*Image
].Blue
;
253 Blt
->Blue
= *Image
++;
254 Blt
->Green
= *Image
++;
259 return EFI_UNSUPPORTED
;
265 ImageIndex
= (UINTN
) (Image
- ImageHeader
);
266 if ((ImageIndex
% 4) != 0) {
268 // Bmp Image starts each row on a 32-bit boundary!
270 Image
= Image
+ (4 - (ImageIndex
% 4));
285 Use Console Control Protocol to lock the Console In Spliter virtual handle.
286 This is the ConInHandle and ConIn handle in the EFI system table. All key
287 presses will be ignored until the Password is typed in. The only way to
288 disable the password is to type it in to a ConIn device.
291 Password - Password used to lock ConIn device
296 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo
298 EFI_UNSUPPORTED - Logo not found
303 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
305 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, (VOID
**) &ConsoleControl
);
306 if (EFI_ERROR (Status
)) {
307 return EFI_UNSUPPORTED
;
310 Status
= ConsoleControl
->LockStdIn (ConsoleControl
, Password
);
317 IN EFI_GUID
*LogoFile
323 Use Console Control to turn off UGA based Simple Text Out consoles from going
324 to the UGA device. Put up LogoFile on every UGA device that is a console
328 LogoFile - File name of logo to display on the center of the screen.
333 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo
335 EFI_UNSUPPORTED - Logo not found
340 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
341 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
342 EFI_OEM_BADGING_PROTOCOL
*Badging
;
352 EFI_UGA_PIXEL
*UgaBlt
;
356 EFI_BADGING_FORMAT Format
;
357 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute
;
363 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, (VOID
**) &ConsoleControl
);
364 if (EFI_ERROR (Status
)) {
365 return EFI_UNSUPPORTED
;
368 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiUgaDrawProtocolGuid
, (VOID
**) &UgaDraw
);
369 if (EFI_ERROR (Status
)) {
370 return EFI_UNSUPPORTED
;
374 Status
= gBS
->LocateProtocol (&gEfiOEMBadgingProtocolGuid
, NULL
, (VOID
**) &Badging
);
376 ConsoleControl
->SetMode (ConsoleControl
, EfiConsoleControlScreenGraphics
);
378 Status
= UgaDraw
->GetMode (UgaDraw
, &SizeOfX
, &SizeOfY
, &ColorDepth
, &RefreshRate
);
379 if (EFI_ERROR (Status
)) {
380 return EFI_UNSUPPORTED
;
388 if (Badging
!= NULL
) {
389 Status
= Badging
->GetImage (
399 if (EFI_ERROR (Status
)) {
404 // Currently only support BMP format
406 if (Format
!= EfiBadgingFormatBMP
) {
407 gBS
->FreePool (ImageData
);
411 Status
= GetGraphicsBitMapFromFV (LogoFile
, (VOID
**) &ImageData
, &ImageSize
);
412 if (EFI_ERROR (Status
)) {
413 return EFI_UNSUPPORTED
;
418 Attribute
= EfiBadgingDisplayAttributeCenter
;
422 Status
= ConvertBmpToUgaBlt (
430 if (EFI_ERROR (Status
)) {
431 gBS
->FreePool (ImageData
);
436 case EfiBadgingDisplayAttributeLeftTop
:
441 case EfiBadgingDisplayAttributeCenterTop
:
442 DestX
= (SizeOfX
- Width
) / 2;
446 case EfiBadgingDisplayAttributeRightTop
:
447 DestX
= (SizeOfX
- Width
- CoordinateX
);
448 DestY
= CoordinateY
;;
451 case EfiBadgingDisplayAttributeCenterRight
:
452 DestX
= (SizeOfX
- Width
- CoordinateX
);
453 DestY
= (SizeOfY
- Height
) / 2;
456 case EfiBadgingDisplayAttributeRightBottom
:
457 DestX
= (SizeOfX
- Width
- CoordinateX
);
458 DestY
= (SizeOfY
- Height
- CoordinateY
);
461 case EfiBadgingDisplayAttributeCenterBottom
:
462 DestX
= (SizeOfX
- Width
) / 2;
463 DestY
= (SizeOfY
- Height
- CoordinateY
);
466 case EfiBadgingDisplayAttributeLeftBottom
:
468 DestY
= (SizeOfY
- Height
- CoordinateY
);
471 case EfiBadgingDisplayAttributeCenterLeft
:
473 DestY
= (SizeOfY
- Height
) / 2;
476 case EfiBadgingDisplayAttributeCenter
:
477 DestX
= (SizeOfX
- Width
) / 2;
478 DestY
= (SizeOfY
- Height
) / 2;
487 if ((DestX
>= 0) && (DestY
>= 0)) {
488 Status
= UgaDraw
->Blt (
491 EfiUgaBltBufferToVideo
,
498 Width
* sizeof (EFI_UGA_PIXEL
)
502 gBS
->FreePool (ImageData
);
503 gBS
->FreePool (UgaBlt
);
505 if (Badging
== NULL
) {
522 Use Console Control to turn on UGA based Simple Text Out consoles. The UGA
523 Simple Text Out screens will now be synced up with all non UGA output devices
531 EFI_SUCCESS - UGA devices are back in text mode and synced up.
532 EFI_UNSUPPORTED - Logo not found
537 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
539 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, (VOID
**) &ConsoleControl
);
540 if (EFI_ERROR (Status
)) {
541 return EFI_UNSUPPORTED
;
544 return ConsoleControl
->SetMode (ConsoleControl
, EfiConsoleControlScreenText
);
547 static EFI_UGA_PIXEL mEfiColors
[16] = {
548 { 0x00, 0x00, 0x00, 0x00 },
549 { 0x98, 0x00, 0x00, 0x00 },
550 { 0x00, 0x98, 0x00, 0x00 },
551 { 0x98, 0x98, 0x00, 0x00 },
552 { 0x00, 0x00, 0x98, 0x00 },
553 { 0x98, 0x00, 0x98, 0x00 },
554 { 0x00, 0x98, 0x98, 0x00 },
555 { 0x98, 0x98, 0x98, 0x00 },
556 { 0x10, 0x10, 0x10, 0x00 },
557 { 0xff, 0x10, 0x10, 0x00 },
558 { 0x10, 0xff, 0x10, 0x00 },
559 { 0xff, 0xff, 0x10, 0x00 },
560 { 0x10, 0x10, 0xff, 0x00 },
561 { 0xf0, 0x10, 0xff, 0x00 },
562 { 0x10, 0xff, 0xff, 0x00 },
563 { 0xff, 0xff, 0xff, 0x00 }
569 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
,
570 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*Sto
,
573 IN EFI_UGA_PIXEL
*Foreground
,
574 IN EFI_UGA_PIXEL
*Background
,
582 Display string worker for: Print, PrintAt, IPrint, IPrintAt
586 UgaDraw - UGA draw protocol interface
588 Sto - Simple text out protocol interface
590 X - X coordinate to start printing
592 Y - Y coordinate to start printing
594 Foreground - Foreground color
596 Background - Background color
600 args - Print arguments
604 EFI_SUCCESS - success
605 EFI_OUT_OF_RESOURCES - out of resources
615 CHAR16
*UnicodeWeight
;
616 EFI_NARROW_GLYPH
*Glyph
;
617 EFI_HII_PROTOCOL
*Hii
;
618 EFI_UGA_PIXEL
*LineBuffer
;
619 UINT32 HorizontalResolution
;
620 UINT32 VerticalResolution
;
627 // For now, allocate an arbitrarily long buffer
629 Buffer
= AllocateZeroPool (0x10000);
630 if (Buffer
== NULL
) {
631 return EFI_OUT_OF_RESOURCES
;
634 UgaDraw
->GetMode (UgaDraw
, &HorizontalResolution
, &VerticalResolution
, &ColorDepth
, &RefreshRate
);
636 LineBuffer
= AllocatePool (sizeof (EFI_UGA_PIXEL
) * HorizontalResolution
* GLYPH_WIDTH
* GLYPH_HEIGHT
);
637 if (LineBuffer
== NULL
) {
638 gBS
->FreePool (Buffer
);
639 return EFI_OUT_OF_RESOURCES
;
642 Status
= gBS
->LocateProtocol (&gEfiHiiProtocolGuid
, NULL
, (VOID
**) &Hii
);
643 if (EFI_ERROR (Status
)) {
647 UnicodeVSPrint (Buffer
, 0x10000, fmt
, args
);
649 UnicodeWeight
= (CHAR16
*) Buffer
;
651 for (Index
= 0; UnicodeWeight
[Index
] != 0; Index
++) {
652 if (UnicodeWeight
[Index
] == CHAR_BACKSPACE
||
653 UnicodeWeight
[Index
] == CHAR_LINEFEED
||
654 UnicodeWeight
[Index
] == CHAR_CARRIAGE_RETURN
) {
655 UnicodeWeight
[Index
] = 0;
659 for (Index
= 0; Index
< StrLen (Buffer
); Index
++) {
660 StringIndex
= (UINT16
) Index
;
661 Status
= Hii
->GetGlyph (Hii
, UnicodeWeight
, &StringIndex
, (UINT8
**) &Glyph
, &GlyphWidth
, &GlyphStatus
);
662 if (EFI_ERROR (Status
)) {
666 if (Foreground
== NULL
|| Background
== NULL
) {
667 Status
= Hii
->GlyphToBlt (
670 mEfiColors
[Sto
->Mode
->Attribute
& 0x0f],
671 mEfiColors
[Sto
->Mode
->Attribute
>> 4],
675 &LineBuffer
[Index
* GLYPH_WIDTH
]
678 Status
= Hii
->GlyphToBlt (
686 &LineBuffer
[Index
* GLYPH_WIDTH
]
692 // Blt a character to the screen
694 Status
= UgaDraw
->Blt (
697 EfiUgaBltBufferToVideo
,
702 GLYPH_WIDTH
* StrLen (Buffer
),
704 GLYPH_WIDTH
* StrLen (Buffer
) * sizeof (EFI_UGA_PIXEL
)
708 gBS
->FreePool (LineBuffer
);
709 gBS
->FreePool (Buffer
);
718 IN EFI_UGA_PIXEL
*ForeGround
, OPTIONAL
719 IN EFI_UGA_PIXEL
*BackGround
, OPTIONAL
727 Prints a formatted unicode string to the default console
731 X - X coordinate to start printing
733 Y - Y coordinate to start printing
735 ForeGround - Foreground color
737 BackGround - Background color
741 ... - Print arguments
745 Length of string printed to the console
750 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
751 EFI_SIMPLE_TEXT_OUT_PROTOCOL
*Sto
;
755 VA_START (Args
, Fmt
);
757 Handle
= gST
->ConsoleOutHandle
;
759 Status
= gBS
->HandleProtocol (
761 &gEfiUgaDrawProtocolGuid
,
765 if (EFI_ERROR (Status
)) {
769 Status
= gBS
->HandleProtocol (
771 &gEfiSimpleTextOutProtocolGuid
,
775 if (EFI_ERROR (Status
)) {
779 return _IPrint (UgaDraw
, Sto
, X
, Y
, ForeGround
, BackGround
, Fmt
, Args
);