3 Copyright (c) 2004 - 2007, 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 Basic Ascii AvSPrintf() function named VSPrint(). VSPrint() enables very
19 simple implemenation of SPrint() and Print() to support debug.
21 You can not Print more than EFI_DRIVER_LIB_MAX_PRINT_BUFFER characters at a
22 time. This makes the implementation very simple.
24 VSPrint, Print, SPrint format specification has the follwoing form
32 ',' - Place commas in numberss
33 '0' - Prefix for width with zeros
38 '*' - Get width from a UINTN argumnet from the argument list
39 Decimal number that represents width of print
42 'X' - argument is a UINTN hex number, prefix '0'
43 'x' - argument is a hex number
44 'd' - argument is a decimal number
45 'a' - argument is an ascii string
46 'S','s' - argument is an Unicode string
47 'g' - argument is a pointer to an EFI_GUID
48 't' - argument is a pointer to an EFI_TIME structure
49 'c' - argument is an ascii character
50 'r' - argument is EFI_STATUS
56 #include "EfiDriverLib.h"
57 #include "TianoCommon.h"
58 #include "EfiCommonLib.h"
59 #include "PrintWidth.h"
60 #include "EfiPrintLib.h"
62 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
63 #include EFI_PROTOCOL_DEFINITION (HiiFont)
65 #include EFI_PROTOCOL_DEFINITION (Hii)
68 static EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors
[16] = {
69 {0x00, 0x00, 0x00, 0x00},
70 {0x98, 0x00, 0x00, 0x00},
71 {0x00, 0x98, 0x00, 0x00},
72 {0x98, 0x98, 0x00, 0x00},
73 {0x00, 0x00, 0x98, 0x00},
74 {0x98, 0x00, 0x98, 0x00},
75 {0x00, 0x98, 0x98, 0x00},
76 {0x98, 0x98, 0x98, 0x00},
77 {0x10, 0x10, 0x10, 0x00},
78 {0xff, 0x10, 0x10, 0x00},
79 {0x10, 0xff, 0x10, 0x00},
80 {0xff, 0xff, 0x10, 0x00},
81 {0x10, 0x10, 0xff, 0x00},
82 {0xf0, 0x10, 0xff, 0x00},
83 {0x10, 0xff, 0xff, 0x00},
84 {0xff, 0xff, 0xff, 0x00},
90 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
91 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
,
92 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*Sto
,
95 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Foreground
,
96 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Background
,
104 Display string worker for: Print, PrintAt, IPrint, IPrintAt
108 GraphicsOutput - Graphics output protocol interface
110 UgaDraw - UGA draw protocol interface
112 Sto - Simple text out protocol interface
114 X - X coordinate to start printing
116 Y - Y coordinate to start printing
118 Foreground - Foreground color
120 Background - Background color
124 args - Print arguments
128 EFI_SUCCESS - success
129 EFI_OUT_OF_RESOURCES - out of resources
136 CHAR16
*UnicodeWeight
;
137 UINT32 HorizontalResolution
;
138 UINT32 VerticalResolution
;
143 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
144 EFI_HII_FONT_PROTOCOL
*HiiFont
;
145 EFI_IMAGE_OUTPUT
*Blt
;
146 EFI_FONT_DISPLAY_INFO
*FontInfo
;
148 EFI_HII_PROTOCOL
*Hii
;
152 EFI_NARROW_GLYPH
*Glyph
;
153 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*LineBuffer
;
157 // For now, allocate an arbitrarily long buffer
159 Buffer
= EfiLibAllocateZeroPool (0x10000);
160 if (Buffer
== NULL
) {
161 return EFI_OUT_OF_RESOURCES
;
164 if (GraphicsOutput
!= NULL
) {
165 HorizontalResolution
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
166 VerticalResolution
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
168 UgaDraw
->GetMode (UgaDraw
, &HorizontalResolution
, &VerticalResolution
, &ColorDepth
, &RefreshRate
);
170 ASSERT ((HorizontalResolution
!= 0) && (VerticalResolution
!=0));
172 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
175 ASSERT (GraphicsOutput
!= NULL
);
176 Status
= gBS
->LocateProtocol (&gEfiHiiFontProtocolGuid
, NULL
, (VOID
**) &HiiFont
);
177 if (EFI_ERROR (Status
)) {
182 Status
= gBS
->LocateProtocol (&gEfiHiiProtocolGuid
, NULL
, (VOID
**)&Hii
);
183 if (EFI_ERROR (Status
)) {
186 LineBufferLen
= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * HorizontalResolution
* GLYPH_HEIGHT
;
187 LineBuffer
= EfiLibAllocatePool (LineBufferLen
);
188 if (LineBuffer
== NULL
) {
189 Status
= EFI_OUT_OF_RESOURCES
;
194 VSPrint (Buffer
, 0x10000, fmt
, args
);
196 UnicodeWeight
= (CHAR16
*) Buffer
;
198 for (Index
= 0; UnicodeWeight
[Index
] != 0; Index
++) {
199 if (UnicodeWeight
[Index
] == CHAR_BACKSPACE
||
200 UnicodeWeight
[Index
] == CHAR_LINEFEED
||
201 UnicodeWeight
[Index
] == CHAR_CARRIAGE_RETURN
) {
202 UnicodeWeight
[Index
] = 0;
206 BufferLen
= EfiStrLen (Buffer
);
208 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
209 LineBufferLen
= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * HorizontalResolution
* EFI_GLYPH_HEIGHT
;
210 if (EFI_GLYPH_WIDTH
* EFI_GLYPH_HEIGHT
* sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * BufferLen
> LineBufferLen
) {
211 Status
= EFI_INVALID_PARAMETER
;
215 Blt
= (EFI_IMAGE_OUTPUT
*) EfiLibAllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT
));
217 Status
= EFI_OUT_OF_RESOURCES
;
221 Blt
->Width
= (UINT16
) (HorizontalResolution
);
222 Blt
->Height
= (UINT16
) (VerticalResolution
);
223 Blt
->Image
.Screen
= GraphicsOutput
;
225 FontInfo
= (EFI_FONT_DISPLAY_INFO
*) EfiLibAllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO
));
226 if (FontInfo
== NULL
) {
227 Status
= EFI_OUT_OF_RESOURCES
;
230 if (Foreground
!= NULL
) {
231 EfiCopyMem (&FontInfo
->ForegroundColor
, Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
234 &FontInfo
->ForegroundColor
,
235 &mEfiColors
[Sto
->Mode
->Attribute
& 0x0f],
236 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
239 if (Background
!= NULL
) {
240 EfiCopyMem (&FontInfo
->BackgroundColor
, Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
243 &FontInfo
->BackgroundColor
,
244 &mEfiColors
[Sto
->Mode
->Attribute
>> 4],
245 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
249 Status
= HiiFont
->StringToImage (
251 EFI_HII_IGNORE_IF_NO_GLYPH
| EFI_HII_DIRECT_TO_SCREEN
,
265 if (GLYPH_WIDTH
* GLYPH_HEIGHT
* sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * BufferLen
> LineBufferLen
) {
266 Status
= EFI_INVALID_PARAMETER
;
270 for (Index
= 0; Index
< BufferLen
; Index
++) {
271 StringIndex
= (UINT16
) Index
;
272 Status
= Hii
->GetGlyph (Hii
, UnicodeWeight
, &StringIndex
, (UINT8
**) &Glyph
, &GlyphWidth
, &GlyphStatus
);
273 if (EFI_ERROR (Status
)) {
277 if (Foreground
== NULL
|| Background
== NULL
) {
278 Status
= Hii
->GlyphToBlt (
281 mEfiColors
[Sto
->Mode
->Attribute
& 0x0f],
282 mEfiColors
[Sto
->Mode
->Attribute
>> 4],
286 &LineBuffer
[Index
* GLYPH_WIDTH
]
289 Status
= Hii
->GlyphToBlt (
297 &LineBuffer
[Index
* GLYPH_WIDTH
]
303 // Blt a character to the screen
305 if (GraphicsOutput
!= NULL
) {
306 Status
= GraphicsOutput
->Blt (
314 GLYPH_WIDTH
* BufferLen
,
316 GLYPH_WIDTH
* BufferLen
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
319 Status
= UgaDraw
->Blt (
321 (EFI_UGA_PIXEL
*) LineBuffer
,
322 EfiUgaBltBufferToVideo
,
327 GLYPH_WIDTH
* BufferLen
,
329 GLYPH_WIDTH
* BufferLen
* sizeof (EFI_UGA_PIXEL
)
336 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
337 EfiLibSafeFreePool (Blt
);
338 EfiLibSafeFreePool (FontInfo
);
340 gBS
->FreePool (LineBuffer
);
342 gBS
->FreePool (Buffer
);
351 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*ForeGround
, OPTIONAL
352 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BackGround
, OPTIONAL
360 Prints a formatted unicode string to the default console
364 X - X coordinate to start printing
366 Y - Y coordinate to start printing
368 ForeGround - Foreground color
370 BackGround - Background color
374 ... - Print arguments
378 Length of string printed to the console
383 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
384 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
385 EFI_SIMPLE_TEXT_OUT_PROTOCOL
*Sto
;
389 VA_START (Args
, Fmt
);
391 Handle
= gST
->ConsoleOutHandle
;
393 Status
= gBS
->HandleProtocol (
395 &gEfiGraphicsOutputProtocolGuid
,
396 (VOID
**) &GraphicsOutput
400 if (EFI_ERROR (Status
)) {
401 GraphicsOutput
= NULL
;
403 Status
= gBS
->HandleProtocol (
405 &gEfiUgaDrawProtocolGuid
,
409 if (EFI_ERROR (Status
)) {
414 Status
= gBS
->HandleProtocol (
416 &gEfiSimpleTextOutProtocolGuid
,
420 if (EFI_ERROR (Status
)) {
424 return _IPrint (GraphicsOutput
, UgaDraw
, Sto
, X
, Y
, ForeGround
, BackGround
, Fmt
, Args
);
432 IN CONST CHAR_W
*Format
,
439 SPrint function to process format and place the results in Buffer.
443 Buffer - Wide char buffer to print the results of the parsing of Format into.
445 BufferSize - Maximum number of characters to put into buffer. Zero means no
448 Format - Format string see file header for more details.
450 ... - Vararg list consumed by processing Format.
454 Number of characters printed.
461 VA_START (Marker
, Format
);
462 Return
= VSPrint (Buffer
, BufferSize
, Format
, Marker
);
471 OUT CHAR_W
*StartOfBuffer
,
473 IN CONST CHAR_W
*FormatString
,
480 VSPrint function to process format and place the results in Buffer. Since a
481 VA_LIST is used this rountine allows the nesting of Vararg routines. Thus
482 this is the main print working routine
486 StartOfBuffer - Unicode buffer to print the results of the parsing of Format into.
488 BufferSize - Maximum number of characters to put into buffer. Zero means
491 FormatString - Unicode format string see file header for more details.
493 Marker - Vararg list consumed by processing Format.
497 Number of characters printed.
502 EFI_PRINT_PROTOCOL
*PrintProtocol
;
504 Status
= gBS
->LocateProtocol (
505 &gEfiPrintProtocolGuid
,
507 (VOID
**) &PrintProtocol
509 if (EFI_ERROR (Status
)) {
512 return PrintProtocol
->VSPrint (