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