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