]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Foundation/Library/Dxe/GraphicsLite/Print.c
Add in the 1st version of ECP.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / GraphicsLite / Print.c
CommitLineData
3eb9473e 1/*++\r
2\r
3Copyright (c) 2004 - 2006, Intel Corporation \r
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
62#include EFI_PROTOCOL_DEFINITION (Hii)\r
63\r
64static EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors[16] = {\r
65 0x00, 0x00, 0x00, 0x00,\r
66 0x98, 0x00, 0x00, 0x00,\r
67 0x00, 0x98, 0x00, 0x00,\r
68 0x98, 0x98, 0x00, 0x00,\r
69 0x00, 0x00, 0x98, 0x00,\r
70 0x98, 0x00, 0x98, 0x00,\r
71 0x00, 0x98, 0x98, 0x00,\r
72 0x98, 0x98, 0x98, 0x00,\r
73 0x10, 0x10, 0x10, 0x00,\r
74 0xff, 0x10, 0x10, 0x00,\r
75 0x10, 0xff, 0x10, 0x00,\r
76 0xff, 0xff, 0x10, 0x00,\r
77 0x10, 0x10, 0xff, 0x00,\r
78 0xf0, 0x10, 0xff, 0x00,\r
79 0x10, 0xff, 0xff, 0x00,\r
80 0xff, 0xff, 0xff, 0x00,\r
81};\r
82\r
83\r
84UINTN\r
85_IPrint (\r
86 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
87 IN EFI_UGA_DRAW_PROTOCOL *UgaDraw,\r
88 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *Sto,\r
89 IN UINTN X,\r
90 IN UINTN Y,\r
91 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,\r
92 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background,\r
93 IN CHAR16 *fmt,\r
94 IN VA_LIST args\r
95 )\r
96/*++\r
97\r
98Routine Description:\r
99\r
100 Display string worker for: Print, PrintAt, IPrint, IPrintAt\r
101\r
102Arguments:\r
103\r
104 GraphicsOutput - Graphics output protocol interface\r
105\r
106 UgaDraw - UGA draw protocol interface\r
107 \r
108 Sto - Simple text out protocol interface\r
109 \r
110 X - X coordinate to start printing\r
111 \r
112 Y - Y coordinate to start printing\r
113 \r
114 Foreground - Foreground color\r
115 \r
116 Background - Background color\r
117 \r
118 fmt - Format string\r
119 \r
120 args - Print arguments\r
121\r
122Returns: \r
123\r
124 EFI_SUCCESS - success\r
125 EFI_OUT_OF_RESOURCES - out of resources\r
126\r
127--*/\r
128{\r
129 VOID *Buffer;\r
130 EFI_STATUS Status;\r
131 UINT16 GlyphWidth;\r
132 UINT32 GlyphStatus;\r
133 UINT16 StringIndex;\r
134 UINTN Index;\r
135 CHAR16 *UnicodeWeight;\r
136 EFI_NARROW_GLYPH *Glyph;\r
137 EFI_HII_PROTOCOL *Hii;\r
138 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LineBuffer;\r
139 UINT32 HorizontalResolution;\r
140 UINT32 VerticalResolution;\r
141 UINT32 ColorDepth;\r
142 UINT32 RefreshRate;\r
143 UINTN BufferLen;\r
144 UINTN LineBufferLen;\r
145\r
146 GlyphStatus = 0;\r
147\r
148 //\r
149 // For now, allocate an arbitrarily long buffer\r
150 //\r
151 Buffer = EfiLibAllocateZeroPool (0x10000);\r
152 if (Buffer == NULL) {\r
153 return EFI_OUT_OF_RESOURCES;\r
154 }\r
155\r
156 if (GraphicsOutput != NULL) {\r
157 HorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;\r
158 VerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;\r
159 } else {\r
160 UgaDraw->GetMode (UgaDraw, &HorizontalResolution, &VerticalResolution, &ColorDepth, &RefreshRate);\r
161 }\r
162 ASSERT ((HorizontalResolution != 0) && (VerticalResolution !=0));\r
163 \r
164 LineBufferLen = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * HorizontalResolution * GLYPH_HEIGHT;\r
165 LineBuffer = EfiLibAllocatePool (LineBufferLen);\r
166 if (LineBuffer == NULL) {\r
167 gBS->FreePool (Buffer);\r
168 return EFI_OUT_OF_RESOURCES;\r
169 }\r
170\r
171 Status = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, &Hii);\r
172 if (EFI_ERROR (Status)) {\r
173 goto Error;\r
174 }\r
175\r
176 VSPrint (Buffer, 0x10000, fmt, args);\r
177 \r
178 UnicodeWeight = (CHAR16 *) Buffer;\r
179\r
180 for (Index = 0; UnicodeWeight[Index] != 0; Index++) {\r
181 if (UnicodeWeight[Index] == CHAR_BACKSPACE ||\r
182 UnicodeWeight[Index] == CHAR_LINEFEED ||\r
183 UnicodeWeight[Index] == CHAR_CARRIAGE_RETURN) {\r
184 UnicodeWeight[Index] = 0;\r
185 }\r
186 }\r
187\r
188 BufferLen = EfiStrLen (Buffer);\r
189\r
190 if (GLYPH_WIDTH * GLYPH_HEIGHT * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * BufferLen > LineBufferLen) {\r
191 Status = EFI_INVALID_PARAMETER;\r
192 goto Error;\r
193 }\r
194\r
195 for (Index = 0; Index < BufferLen; Index++) {\r
196 StringIndex = (UINT16) Index;\r
197 Status = Hii->GetGlyph (Hii, UnicodeWeight, &StringIndex, (UINT8 **) &Glyph, &GlyphWidth, &GlyphStatus);\r
198 if (EFI_ERROR (Status)) {\r
199 goto Error;\r
200 }\r
201\r
202 if (Foreground == NULL || Background == NULL) {\r
203 Status = Hii->GlyphToBlt (\r
204 Hii,\r
205 (UINT8 *) Glyph,\r
206 mEfiColors[Sto->Mode->Attribute & 0x0f],\r
207 mEfiColors[Sto->Mode->Attribute >> 4],\r
208 BufferLen,\r
209 GlyphWidth,\r
210 GLYPH_HEIGHT,\r
211 &LineBuffer[Index * GLYPH_WIDTH]\r
212 );\r
213 } else {\r
214 Status = Hii->GlyphToBlt (\r
215 Hii,\r
216 (UINT8 *) Glyph,\r
217 *Foreground,\r
218 *Background,\r
219 BufferLen,\r
220 GlyphWidth,\r
221 GLYPH_HEIGHT,\r
222 &LineBuffer[Index * GLYPH_WIDTH]\r
223 );\r
224 }\r
225 }\r
226\r
227 //\r
228 // Blt a character to the screen\r
229 //\r
230 if (GraphicsOutput != NULL) {\r
231 Status = GraphicsOutput->Blt (\r
232 GraphicsOutput,\r
233 LineBuffer,\r
234 EfiBltBufferToVideo,\r
235 0,\r
236 0,\r
237 X,\r
238 Y,\r
239 GLYPH_WIDTH * BufferLen,\r
240 GLYPH_HEIGHT,\r
241 GLYPH_WIDTH * BufferLen * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
242 );\r
243 } else {\r
244 Status = UgaDraw->Blt (\r
245 UgaDraw,\r
246 (EFI_UGA_PIXEL *) LineBuffer,\r
247 EfiUgaBltBufferToVideo,\r
248 0,\r
249 0,\r
250 X,\r
251 Y,\r
252 GLYPH_WIDTH * BufferLen,\r
253 GLYPH_HEIGHT,\r
254 GLYPH_WIDTH * BufferLen * sizeof (EFI_UGA_PIXEL)\r
255 );\r
256 }\r
257\r
258Error:\r
259 gBS->FreePool (LineBuffer);\r
260 gBS->FreePool (Buffer);\r
261 return Status;\r
262}\r
263\r
264\r
265UINTN\r
266PrintXY (\r
267 IN UINTN X,\r
268 IN UINTN Y,\r
269 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ForeGround, OPTIONAL\r
270 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BackGround, OPTIONAL\r
271 IN CHAR_W *Fmt,\r
272 ...\r
273 )\r
274/*++\r
275\r
276Routine Description:\r
277\r
278 Prints a formatted unicode string to the default console\r
279\r
280Arguments:\r
281\r
282 X - X coordinate to start printing\r
283 \r
284 Y - Y coordinate to start printing\r
285 \r
286 ForeGround - Foreground color\r
287 \r
288 BackGround - Background color\r
289\r
290 Fmt - Format string\r
291\r
292 ... - Print arguments\r
293\r
294Returns:\r
295\r
296 Length of string printed to the console\r
297\r
298--*/\r
299{\r
300 EFI_HANDLE Handle;\r
301 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
302 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
303 EFI_SIMPLE_TEXT_OUT_PROTOCOL *Sto;\r
304 EFI_STATUS Status;\r
305 VA_LIST Args;\r
306\r
307 VA_START (Args, Fmt);\r
308\r
309 Handle = gST->ConsoleOutHandle;\r
310\r
311 Status = gBS->HandleProtocol (\r
312 Handle,\r
313 &gEfiGraphicsOutputProtocolGuid,\r
314 &GraphicsOutput\r
315 );\r
316\r
317 UgaDraw = NULL;\r
318 if (EFI_ERROR (Status)) {\r
319 GraphicsOutput = NULL;\r
320\r
321 Status = gBS->HandleProtocol (\r
322 Handle,\r
323 &gEfiUgaDrawProtocolGuid,\r
324 &UgaDraw\r
325 );\r
326\r
327 if (EFI_ERROR (Status)) {\r
328 return Status;\r
329 }\r
330 }\r
331\r
332 Status = gBS->HandleProtocol (\r
333 Handle,\r
334 &gEfiSimpleTextOutProtocolGuid,\r
335 &Sto\r
336 );\r
337\r
338 if (EFI_ERROR (Status)) {\r
339 return Status;\r
340 }\r
341\r
342 return _IPrint (GraphicsOutput, UgaDraw, Sto, X, Y, ForeGround, BackGround, Fmt, Args);\r
343}\r
344\r
345\r
346UINTN\r
347SPrint (\r
348 OUT CHAR_W *Buffer,\r
349 IN UINTN BufferSize,\r
350 IN CONST CHAR_W *Format,\r
351 ...\r
352 )\r
353/*++\r
354\r
355Routine Description:\r
356\r
357 SPrint function to process format and place the results in Buffer.\r
358\r
359Arguments:\r
360\r
361 Buffer - Wide char buffer to print the results of the parsing of Format into.\r
362\r
363 BufferSize - Maximum number of characters to put into buffer. Zero means no \r
364 limit.\r
365\r
366 Format - Format string see file header for more details.\r
367\r
368 ... - Vararg list consumed by processing Format.\r
369\r
370Returns: \r
371\r
372 Number of characters printed.\r
373\r
374--*/\r
375{\r
376 UINTN Return;\r
377 VA_LIST Marker;\r
378\r
379 VA_START (Marker, Format);\r
380 Return = VSPrint (Buffer, BufferSize, Format, Marker);\r
381 VA_END (Marker);\r
382\r
383 return Return;\r
384}\r
385\r
386UINTN\r
387VSPrint (\r
388 OUT CHAR_W *StartOfBuffer,\r
389 IN UINTN BufferSize,\r
390 IN CONST CHAR_W *FormatString,\r
391 IN VA_LIST Marker\r
392 )\r
393/*++\r
394\r
395Routine Description:\r
396\r
397 VSPrint function to process format and place the results in Buffer. Since a \r
398 VA_LIST is used this rountine allows the nesting of Vararg routines. Thus \r
399 this is the main print working routine\r
400\r
401Arguments:\r
402\r
403 StartOfBuffer - Unicode buffer to print the results of the parsing of Format into.\r
404\r
405 BufferSize - Maximum number of characters to put into buffer. Zero means \r
406 no limit.\r
407\r
408 FormatString - Unicode format string see file header for more details.\r
409\r
410 Marker - Vararg list consumed by processing Format.\r
411\r
412Returns: \r
413\r
414 Number of characters printed.\r
415\r
416--*/\r
417{\r
418 EFI_STATUS Status;\r
419 EFI_PRINT_PROTOCOL *PrintProtocol;\r
420\r
421 Status = gBS->LocateProtocol (\r
422 &gEfiPrintProtocolGuid,\r
423 NULL,\r
424 &PrintProtocol\r
425 );\r
426 if (EFI_ERROR (Status)) {\r
427 return 0;\r
428 } else {\r
429 return PrintProtocol->VSPrint (\r
430 StartOfBuffer,\r
431 BufferSize,\r
432 FormatString,\r
433 Marker\r
434 );\r
435 }\r
436}\r