]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/Dxe/GraphicsLite/Print.c
Update the copyright notice format
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / GraphicsLite / Print.c
1 /*++
2
3 Copyright (c) 2004 - 2007, 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 EFI_SUCCESS - success
129 EFI_OUT_OF_RESOURCES - out of resources
130
131 --*/
132 {
133 VOID *Buffer;
134 EFI_STATUS Status;
135 UINTN Index;
136 CHAR16 *UnicodeWeight;
137 UINT32 HorizontalResolution;
138 UINT32 VerticalResolution;
139 UINT32 ColorDepth;
140 UINT32 RefreshRate;
141 UINTN BufferLen;
142 UINTN LineBufferLen;
143 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
144 EFI_HII_FONT_PROTOCOL *HiiFont;
145 EFI_IMAGE_OUTPUT *Blt;
146 EFI_FONT_DISPLAY_INFO *FontInfo;
147 #else
148 EFI_HII_PROTOCOL *Hii;
149 UINT16 GlyphWidth;
150 UINT32 GlyphStatus;
151 UINT16 StringIndex;
152 EFI_NARROW_GLYPH *Glyph;
153 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LineBuffer;
154 #endif
155
156 //
157 // For now, allocate an arbitrarily long buffer
158 //
159 Buffer = EfiLibAllocateZeroPool (0x10000);
160 if (Buffer == NULL) {
161 return EFI_OUT_OF_RESOURCES;
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 gBS->FreePool (LineBuffer);
341 #endif
342 gBS->FreePool (Buffer);
343 return Status;
344 }
345
346
347 UINTN
348 PrintXY (
349 IN UINTN X,
350 IN UINTN Y,
351 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ForeGround, OPTIONAL
352 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BackGround, OPTIONAL
353 IN CHAR_W *Fmt,
354 ...
355 )
356 /*++
357
358 Routine Description:
359
360 Prints a formatted unicode string to the default console
361
362 Arguments:
363
364 X - X coordinate to start printing
365
366 Y - Y coordinate to start printing
367
368 ForeGround - Foreground color
369
370 BackGround - Background color
371
372 Fmt - Format string
373
374 ... - Print arguments
375
376 Returns:
377
378 Length of string printed to the console
379
380 --*/
381 {
382 EFI_HANDLE Handle;
383 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
384 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
385 EFI_SIMPLE_TEXT_OUT_PROTOCOL *Sto;
386 EFI_STATUS Status;
387 VA_LIST Args;
388
389 VA_START (Args, Fmt);
390
391 Handle = gST->ConsoleOutHandle;
392
393 Status = gBS->HandleProtocol (
394 Handle,
395 &gEfiGraphicsOutputProtocolGuid,
396 (VOID **) &GraphicsOutput
397 );
398
399 UgaDraw = NULL;
400 if (EFI_ERROR (Status)) {
401 GraphicsOutput = NULL;
402
403 Status = gBS->HandleProtocol (
404 Handle,
405 &gEfiUgaDrawProtocolGuid,
406 (VOID **) &UgaDraw
407 );
408
409 if (EFI_ERROR (Status)) {
410 return Status;
411 }
412 }
413
414 Status = gBS->HandleProtocol (
415 Handle,
416 &gEfiSimpleTextOutProtocolGuid,
417 (VOID **) &Sto
418 );
419
420 if (EFI_ERROR (Status)) {
421 return Status;
422 }
423
424 return _IPrint (GraphicsOutput, UgaDraw, Sto, X, Y, ForeGround, BackGround, Fmt, Args);
425 }
426
427
428 UINTN
429 SPrint (
430 OUT CHAR_W *Buffer,
431 IN UINTN BufferSize,
432 IN CONST CHAR_W *Format,
433 ...
434 )
435 /*++
436
437 Routine Description:
438
439 SPrint function to process format and place the results in Buffer.
440
441 Arguments:
442
443 Buffer - Wide char buffer to print the results of the parsing of Format into.
444
445 BufferSize - Maximum number of characters to put into buffer. Zero means no
446 limit.
447
448 Format - Format string see file header for more details.
449
450 ... - Vararg list consumed by processing Format.
451
452 Returns:
453
454 Number of characters printed.
455
456 --*/
457 {
458 UINTN Return;
459 VA_LIST Marker;
460
461 VA_START (Marker, Format);
462 Return = VSPrint (Buffer, BufferSize, Format, Marker);
463 VA_END (Marker);
464
465 return Return;
466 }
467
468 UINTN
469 EFIAPI
470 VSPrint (
471 OUT CHAR_W *StartOfBuffer,
472 IN UINTN BufferSize,
473 IN CONST CHAR_W *FormatString,
474 IN VA_LIST Marker
475 )
476 /*++
477
478 Routine Description:
479
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
483
484 Arguments:
485
486 StartOfBuffer - Unicode buffer to print the results of the parsing of Format into.
487
488 BufferSize - Maximum number of characters to put into buffer. Zero means
489 no limit.
490
491 FormatString - Unicode format string see file header for more details.
492
493 Marker - Vararg list consumed by processing Format.
494
495 Returns:
496
497 Number of characters printed.
498
499 --*/
500 {
501 EFI_STATUS Status;
502 EFI_PRINT_PROTOCOL *PrintProtocol;
503
504 Status = gBS->LocateProtocol (
505 &gEfiPrintProtocolGuid,
506 NULL,
507 (VOID **) &PrintProtocol
508 );
509 if (EFI_ERROR (Status)) {
510 return 0;
511 } else {
512 return PrintProtocol->VSPrint (
513 StartOfBuffer,
514 BufferSize,
515 FormatString,
516 Marker
517 );
518 }
519 }