]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/Dxe/GraphicsLite/Print.c
Maintainers.txt: Remove EdkCompatibilityPkg information
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / GraphicsLite / Print.c
1 /*++
2
3 Copyright (c) 2004 - 2012, 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 UINTN LengthOfPrinted;
394
395 Handle = gST->ConsoleOutHandle;
396
397 GraphicsOutput = NULL;
398 UgaDraw = NULL;
399 Status = gBS->HandleProtocol (
400 Handle,
401 &gEfiGraphicsOutputProtocolGuid,
402 (VOID **) &GraphicsOutput
403 );
404
405 if (EFI_ERROR (Status) || (GraphicsOutput == NULL)) {
406 GraphicsOutput = NULL;
407
408 Status = gBS->HandleProtocol (
409 Handle,
410 &gEfiUgaDrawProtocolGuid,
411 (VOID **) &UgaDraw
412 );
413
414 if (EFI_ERROR (Status) || (UgaDraw == NULL)) {
415 return 0;
416 }
417 }
418
419 Sto = NULL;
420 Status = gBS->HandleProtocol (
421 Handle,
422 &gEfiSimpleTextOutProtocolGuid,
423 (VOID **) &Sto
424 );
425
426 if (EFI_ERROR (Status) || (Sto == NULL)) {
427 return 0;
428 }
429
430 VA_START (Args, Fmt);
431 LengthOfPrinted = _IPrint (GraphicsOutput, UgaDraw, Sto, X, Y, ForeGround, BackGround, Fmt, Args);
432 VA_END (Args);
433 return LengthOfPrinted;
434 }
435
436
437 UINTN
438 SPrint (
439 OUT CHAR_W *Buffer,
440 IN UINTN BufferSize,
441 IN CONST CHAR_W *Format,
442 ...
443 )
444 /*++
445
446 Routine Description:
447
448 SPrint function to process format and place the results in Buffer.
449
450 Arguments:
451
452 Buffer - Wide char buffer to print the results of the parsing of Format into.
453
454 BufferSize - Maximum number of characters to put into buffer. Zero means no
455 limit.
456
457 Format - Format string see file header for more details.
458
459 ... - Vararg list consumed by processing Format.
460
461 Returns:
462
463 Number of characters printed.
464
465 --*/
466 {
467 UINTN Return;
468 VA_LIST Marker;
469
470 VA_START (Marker, Format);
471 Return = VSPrint (Buffer, BufferSize, Format, Marker);
472 VA_END (Marker);
473
474 return Return;
475 }
476
477 UINTN
478 EFIAPI
479 VSPrint (
480 OUT CHAR_W *StartOfBuffer,
481 IN UINTN BufferSize,
482 IN CONST CHAR_W *FormatString,
483 IN VA_LIST Marker
484 )
485 /*++
486
487 Routine Description:
488
489 VSPrint function to process format and place the results in Buffer. Since a
490 VA_LIST is used this rountine allows the nesting of Vararg routines. Thus
491 this is the main print working routine
492
493 Arguments:
494
495 StartOfBuffer - Unicode buffer to print the results of the parsing of Format into.
496
497 BufferSize - Maximum number of characters to put into buffer. Zero means
498 no limit.
499
500 FormatString - Unicode format string see file header for more details.
501
502 Marker - Vararg list consumed by processing Format.
503
504 Returns:
505
506 Number of characters printed.
507
508 --*/
509 {
510 EFI_STATUS Status;
511 EFI_PRINT_PROTOCOL *PrintProtocol;
512
513 Status = gBS->LocateProtocol (
514 &gEfiPrintProtocolGuid,
515 NULL,
516 (VOID **) &PrintProtocol
517 );
518 if (EFI_ERROR (Status)) {
519 return 0;
520 } else {
521 return PrintProtocol->VSPrint (
522 StartOfBuffer,
523 BufferSize,
524 FormatString,
525 Marker
526 );
527 }
528 }