]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/Dxe/GraphicsLite/Print.c
MdeModulePkg PciBusDxe: Add typecast to eliminate possible "loss of precision" warning.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / GraphicsLite / Print.c
1 /*++
2
3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
4 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
8
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.
11
12 Module Name:
13
14 Print.c
15
16 Abstract:
17
18 Basic Ascii AvSPrintf() function named VSPrint(). VSPrint() enables very
19 simple implemenation of SPrint() and Print() to support debug.
20
21 You can not Print more than EFI_DRIVER_LIB_MAX_PRINT_BUFFER characters at a
22 time. This makes the implementation very simple.
23
24 VSPrint, Print, SPrint format specification has the follwoing form
25
26 %[flags][width]type
27
28 flags:
29 '-' - Left justify
30 '+' - Prefix a sign
31 ' ' - Prefix a blank
32 ',' - Place commas in numberss
33 '0' - Prefix for width with zeros
34 'l' - UINT64
35 'L' - UINT64
36
37 width:
38 '*' - Get width from a UINTN argumnet from the argument list
39 Decimal number that represents width of print
40
41 type:
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
51 '%' - Print a %
52
53 --*/
54
55 #include "Tiano.h"
56 #include "EfiDriverLib.h"
57 #include "TianoCommon.h"
58 #include "EfiCommonLib.h"
59 #include "PrintWidth.h"
60 #include "EfiPrintLib.h"
61 #include "Print.h"
62 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
63 #include EFI_PROTOCOL_DEFINITION (HiiFont)
64 #else
65 #include EFI_PROTOCOL_DEFINITION (Hii)
66 #endif
67
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},
85 };
86
87
88 UINTN
89 _IPrint (
90 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,
91 IN EFI_UGA_DRAW_PROTOCOL *UgaDraw,
92 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *Sto,
93 IN UINTN X,
94 IN UINTN Y,
95 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,
96 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background,
97 IN CHAR16 *fmt,
98 IN VA_LIST args
99 )
100 /*++
101
102 Routine Description:
103
104 Display string worker for: Print, PrintAt, IPrint, IPrintAt
105
106 Arguments:
107
108 GraphicsOutput - Graphics output protocol interface
109
110 UgaDraw - UGA draw protocol interface
111
112 Sto - Simple text out protocol interface
113
114 X - X coordinate to start printing
115
116 Y - Y coordinate to start printing
117
118 Foreground - Foreground color
119
120 Background - Background color
121
122 fmt - Format string
123
124 args - Print arguments
125
126 Returns:
127
128 Length of string printed to the console
129
130 --*/
131 {
132 VOID *Buffer;
133 EFI_STATUS Status;
134 UINTN Index;
135 CHAR16 *UnicodeWeight;
136 UINT32 HorizontalResolution;
137 UINT32 VerticalResolution;
138 UINT32 ColorDepth;
139 UINT32 RefreshRate;
140 UINTN BufferLen;
141 UINTN LineBufferLen;
142 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
143 EFI_HII_FONT_PROTOCOL *HiiFont;
144 EFI_IMAGE_OUTPUT *Blt;
145 EFI_FONT_DISPLAY_INFO *FontInfo;
146 #else
147 EFI_HII_PROTOCOL *Hii;
148 UINT16 GlyphWidth;
149 UINT32 GlyphStatus;
150 UINT16 StringIndex;
151 EFI_NARROW_GLYPH *Glyph;
152 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LineBuffer;
153 #endif
154
155 //
156 // For now, allocate an arbitrarily long buffer
157 //
158 BufferLen = 0;
159 Buffer = EfiLibAllocateZeroPool (0x10000);
160 if (Buffer == NULL) {
161 return 0;
162 }
163
164 if (GraphicsOutput != NULL) {
165 HorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
166 VerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;
167 } else {
168 UgaDraw->GetMode (UgaDraw, &HorizontalResolution, &VerticalResolution, &ColorDepth, &RefreshRate);
169 }
170 ASSERT ((HorizontalResolution != 0) && (VerticalResolution !=0));
171
172 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
173 Blt = NULL;
174 FontInfo = NULL;
175 ASSERT (GraphicsOutput != NULL);
176 Status = gBS->LocateProtocol (&gEfiHiiFontProtocolGuid, NULL, (VOID **) &HiiFont);
177 if (EFI_ERROR (Status)) {
178 goto Error;
179 }
180 #else
181 LineBuffer = NULL;
182 Status = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, (VOID**)&Hii);
183 if (EFI_ERROR (Status)) {
184 goto Error;
185 }
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;
190 goto Error;
191 }
192 #endif
193
194 VSPrint (Buffer, 0x10000, fmt, args);
195
196 UnicodeWeight = (CHAR16 *) Buffer;
197
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;
203 }
204 }
205
206 BufferLen = EfiStrLen (Buffer);
207
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;
212 goto Error;
213 }
214
215 Blt = (EFI_IMAGE_OUTPUT *) EfiLibAllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
216 if (Blt == NULL) {
217 Status = EFI_OUT_OF_RESOURCES;
218 goto Error;
219 }
220
221 Blt->Width = (UINT16) (HorizontalResolution);
222 Blt->Height = (UINT16) (VerticalResolution);
223 Blt->Image.Screen = GraphicsOutput;
224
225 FontInfo = (EFI_FONT_DISPLAY_INFO *) EfiLibAllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO));
226 if (FontInfo == NULL) {
227 Status = EFI_OUT_OF_RESOURCES;
228 goto Error;
229 }
230 if (Foreground != NULL) {
231 EfiCopyMem (&FontInfo->ForegroundColor, Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
232 } else {
233 EfiCopyMem (
234 &FontInfo->ForegroundColor,
235 &mEfiColors[Sto->Mode->Attribute & 0x0f],
236 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
237 );
238 }
239 if (Background != NULL) {
240 EfiCopyMem (&FontInfo->BackgroundColor, Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
241 } else {
242 EfiCopyMem (
243 &FontInfo->BackgroundColor,
244 &mEfiColors[Sto->Mode->Attribute >> 4],
245 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
246 );
247 }
248
249 Status = HiiFont->StringToImage (
250 HiiFont,
251 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_DIRECT_TO_SCREEN,
252 Buffer,
253 FontInfo,
254 &Blt,
255 X,
256 Y,
257 NULL,
258 NULL,
259 NULL
260 );
261
262 #else
263 GlyphStatus = 0;
264
265 if (GLYPH_WIDTH * GLYPH_HEIGHT * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * BufferLen > LineBufferLen) {
266 Status = EFI_INVALID_PARAMETER;
267 goto Error;
268 }
269
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)) {
274 goto Error;
275 }
276
277 if (Foreground == NULL || Background == NULL) {
278 Status = Hii->GlyphToBlt (
279 Hii,
280 (UINT8 *) Glyph,
281 mEfiColors[Sto->Mode->Attribute & 0x0f],
282 mEfiColors[Sto->Mode->Attribute >> 4],
283 BufferLen,
284 GlyphWidth,
285 GLYPH_HEIGHT,
286 &LineBuffer[Index * GLYPH_WIDTH]
287 );
288 } else {
289 Status = Hii->GlyphToBlt (
290 Hii,
291 (UINT8 *) Glyph,
292 *Foreground,
293 *Background,
294 BufferLen,
295 GlyphWidth,
296 GLYPH_HEIGHT,
297 &LineBuffer[Index * GLYPH_WIDTH]
298 );
299 }
300 }
301
302 //
303 // Blt a character to the screen
304 //
305 if (GraphicsOutput != NULL) {
306 Status = GraphicsOutput->Blt (
307 GraphicsOutput,
308 LineBuffer,
309 EfiBltBufferToVideo,
310 0,
311 0,
312 X,
313 Y,
314 GLYPH_WIDTH * BufferLen,
315 GLYPH_HEIGHT,
316 GLYPH_WIDTH * BufferLen * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
317 );
318 } else {
319 Status = UgaDraw->Blt (
320 UgaDraw,
321 (EFI_UGA_PIXEL *) LineBuffer,
322 EfiUgaBltBufferToVideo,
323 0,
324 0,
325 X,
326 Y,
327 GLYPH_WIDTH * BufferLen,
328 GLYPH_HEIGHT,
329 GLYPH_WIDTH * BufferLen * sizeof (EFI_UGA_PIXEL)
330 );
331 }
332
333 #endif
334
335 Error:
336 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
337 EfiLibSafeFreePool (Blt);
338 EfiLibSafeFreePool (FontInfo);
339 #else
340 EfiLibSafeFreePool (LineBuffer);
341 #endif
342 gBS->FreePool (Buffer);
343
344 if (EFI_ERROR (Status)) {
345 return 0;
346 }
347
348 return BufferLen;
349 }
350
351
352 UINTN
353 PrintXY (
354 IN UINTN X,
355 IN UINTN Y,
356 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ForeGround, OPTIONAL
357 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BackGround, OPTIONAL
358 IN CHAR_W *Fmt,
359 ...
360 )
361 /*++
362
363 Routine Description:
364
365 Prints a formatted unicode string to the default console
366
367 Arguments:
368
369 X - X coordinate to start printing
370
371 Y - Y coordinate to start printing
372
373 ForeGround - Foreground color
374
375 BackGround - Background color
376
377 Fmt - Format string
378
379 ... - Print arguments
380
381 Returns:
382
383 Length of string printed to the console
384
385 --*/
386 {
387 EFI_HANDLE Handle;
388 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
389 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
390 EFI_SIMPLE_TEXT_OUT_PROTOCOL *Sto;
391 EFI_STATUS Status;
392 VA_LIST Args;
393
394 VA_START (Args, Fmt);
395
396 Handle = gST->ConsoleOutHandle;
397
398 GraphicsOutput = NULL;
399 UgaDraw = NULL;
400 Status = gBS->HandleProtocol (
401 Handle,
402 &gEfiGraphicsOutputProtocolGuid,
403 (VOID **) &GraphicsOutput
404 );
405
406 if (EFI_ERROR (Status) || (GraphicsOutput == NULL)) {
407 GraphicsOutput = NULL;
408
409 Status = gBS->HandleProtocol (
410 Handle,
411 &gEfiUgaDrawProtocolGuid,
412 (VOID **) &UgaDraw
413 );
414
415 if (EFI_ERROR (Status) || (UgaDraw == NULL)) {
416 return 0;
417 }
418 }
419
420 Sto = NULL;
421 Status = gBS->HandleProtocol (
422 Handle,
423 &gEfiSimpleTextOutProtocolGuid,
424 (VOID **) &Sto
425 );
426
427 if (EFI_ERROR (Status) || (Sto == NULL)) {
428 return 0;
429 }
430
431 return _IPrint (GraphicsOutput, UgaDraw, Sto, X, Y, ForeGround, BackGround, Fmt, Args);
432 }
433
434
435 UINTN
436 SPrint (
437 OUT CHAR_W *Buffer,
438 IN UINTN BufferSize,
439 IN CONST CHAR_W *Format,
440 ...
441 )
442 /*++
443
444 Routine Description:
445
446 SPrint function to process format and place the results in Buffer.
447
448 Arguments:
449
450 Buffer - Wide char buffer to print the results of the parsing of Format into.
451
452 BufferSize - Maximum number of characters to put into buffer. Zero means no
453 limit.
454
455 Format - Format string see file header for more details.
456
457 ... - Vararg list consumed by processing Format.
458
459 Returns:
460
461 Number of characters printed.
462
463 --*/
464 {
465 UINTN Return;
466 VA_LIST Marker;
467
468 VA_START (Marker, Format);
469 Return = VSPrint (Buffer, BufferSize, Format, Marker);
470 VA_END (Marker);
471
472 return Return;
473 }
474
475 UINTN
476 EFIAPI
477 VSPrint (
478 OUT CHAR_W *StartOfBuffer,
479 IN UINTN BufferSize,
480 IN CONST CHAR_W *FormatString,
481 IN VA_LIST Marker
482 )
483 /*++
484
485 Routine Description:
486
487 VSPrint function to process format and place the results in Buffer. Since a
488 VA_LIST is used this rountine allows the nesting of Vararg routines. Thus
489 this is the main print working routine
490
491 Arguments:
492
493 StartOfBuffer - Unicode buffer to print the results of the parsing of Format into.
494
495 BufferSize - Maximum number of characters to put into buffer. Zero means
496 no limit.
497
498 FormatString - Unicode format string see file header for more details.
499
500 Marker - Vararg list consumed by processing Format.
501
502 Returns:
503
504 Number of characters printed.
505
506 --*/
507 {
508 EFI_STATUS Status;
509 EFI_PRINT_PROTOCOL *PrintProtocol;
510
511 Status = gBS->LocateProtocol (
512 &gEfiPrintProtocolGuid,
513 NULL,
514 (VOID **) &PrintProtocol
515 );
516 if (EFI_ERROR (Status)) {
517 return 0;
518 } else {
519 return PrintProtocol->VSPrint (
520 StartOfBuffer,
521 BufferSize,
522 FormatString,
523 Marker
524 );
525 }
526 }