]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Library/EdkGraphicsLib/Graphics.c
Make MDE and EdkModule packages avoid all Intel IPF compiler warnings except waning...
[mirror_edk2.git] / EdkModulePkg / Library / EdkGraphicsLib / Graphics.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 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 Graphics.c\r
15\r
16Abstract:\r
17\r
18 Support for Basic Graphics operations.\r
19\r
20 BugBug: Currently *.BMP files are supported. This will be replaced\r
21 when Tiano graphics format is supported.\r
22\r
23--*/\r
24\r
fb5a3ed8 25\r
878ddf1f 26EFI_STATUS\r
27GetGraphicsBitMapFromFV (\r
28 IN EFI_GUID *FileNameGuid,\r
29 OUT VOID **Image,\r
30 OUT UINTN *ImageSize\r
31 )\r
32/*++\r
33\r
34Routine Description:\r
35\r
36 Return the graphics image file named FileNameGuid into Image and return it's\r
37 size in ImageSize. All Firmware Volumes (FV) in the system are searched for the\r
38 file name.\r
39\r
40Arguments:\r
41\r
42 FileNameGuid - File Name of graphics file in the FV(s).\r
43\r
44 Image - Pointer to pointer to return graphics image. If NULL, a \r
45 buffer will be allocated.\r
46\r
47 ImageSize - Size of the graphics Image in bytes. Zero if no image found.\r
48\r
49\r
50Returns: \r
51\r
52 EFI_SUCCESS - Image and ImageSize are valid. \r
53 EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size\r
54 EFI_NOT_FOUND - FileNameGuid not found\r
55\r
56--*/\r
57{\r
58 EFI_STATUS Status;\r
59 UINTN FvProtocolCount;\r
60 EFI_HANDLE *FvHandles;\r
61 EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;\r
62 UINTN Index;\r
63 UINT32 AuthenticationStatus;\r
64\r
65\r
66 Status = gBS->LocateHandleBuffer (\r
67 ByProtocol,\r
68 &gEfiFirmwareVolumeProtocolGuid,\r
69 NULL,\r
70 &FvProtocolCount,\r
71 &FvHandles\r
72 );\r
73 if (EFI_ERROR (Status)) {\r
74 return EFI_NOT_FOUND;\r
75 }\r
76\r
77 for (Index = 0; Index < FvProtocolCount; Index++) {\r
78 Status = gBS->HandleProtocol (\r
79 FvHandles[Index],\r
80 &gEfiFirmwareVolumeProtocolGuid,\r
81 (VOID **) &Fv\r
82 );\r
83\r
84 //\r
85 // Assuming Image and ImageSize are correct on input.\r
86 //\r
87 Status = Fv->ReadSection (\r
88 Fv,\r
89 &gEfiDefaultBmpLogoGuid,\r
90 EFI_SECTION_RAW,\r
91 0,\r
92 Image,\r
93 ImageSize,\r
94 &AuthenticationStatus\r
95 );\r
96 if (!EFI_ERROR (Status)) {\r
97 return EFI_SUCCESS;\r
98 } else if (Status == EFI_BUFFER_TOO_SMALL) {\r
99 //\r
100 // ImageSize updated to needed size so return\r
101 //\r
102 return EFI_BUFFER_TOO_SMALL;\r
103 }\r
104 }\r
105\r
106 return EFI_NOT_FOUND;\r
107}\r
108\r
617de480 109STATIC\r
878ddf1f 110EFI_STATUS\r
406adcd1 111ConvertBmpToGopBlt (\r
878ddf1f 112 IN VOID *BmpImage,\r
113 IN UINTN BmpImageSize,\r
406adcd1 114 IN OUT VOID **GopBlt,\r
115 IN OUT UINTN *GopBltSize,\r
878ddf1f 116 OUT UINTN *PixelHeight,\r
117 OUT UINTN *PixelWidth\r
118 )\r
119/*++\r
120\r
121Routine Description:\r
122\r
123 Convert a *.BMP graphics image to a UGA blt buffer. If a NULL UgaBlt buffer\r
124 is passed in a UgaBlt buffer will be allocated by this routine. If a UgaBlt\r
125 buffer is passed in it will be used if it is big enough.\r
126\r
127Arguments:\r
128\r
129 BmpImage - Pointer to BMP file\r
130\r
131 BmpImageSize - Number of bytes in BmpImage\r
132\r
133 UgaBlt - Buffer containing UGA version of BmpImage.\r
134\r
135 UgaBltSize - Size of UgaBlt in bytes.\r
136\r
137 PixelHeight - Height of UgaBlt/BmpImage in pixels\r
138\r
139 PixelWidth - Width of UgaBlt/BmpImage in pixels\r
140\r
141\r
142Returns: \r
143\r
144 EFI_SUCCESS - UgaBlt and UgaBltSize are returned. \r
145 EFI_UNSUPPORTED - BmpImage is not a valid *.BMP image\r
146 EFI_BUFFER_TOO_SMALL - The passed in UgaBlt buffer is not big enough.\r
147 UgaBltSize will contain the required size.\r
148 EFI_OUT_OF_RESOURCES - No enough buffer to allocate\r
149\r
150--*/\r
151{\r
152 UINT8 *Image;\r
153 UINT8 *ImageHeader;\r
154 BMP_IMAGE_HEADER *BmpHeader;\r
155 BMP_COLOR_MAP *BmpColorMap;\r
406adcd1 156 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
157 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
878ddf1f 158 UINTN BltBufferSize;\r
159 UINTN Index;\r
160 UINTN Height;\r
161 UINTN Width;\r
162 UINTN ImageIndex;\r
d4f397c0 163 BOOLEAN IsAllocated;\r
164 \r
878ddf1f 165 BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;\r
166 if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {\r
167 return EFI_UNSUPPORTED;\r
168 }\r
169\r
170 if (BmpHeader->CompressionType != 0) {\r
171 return EFI_UNSUPPORTED;\r
172 }\r
173\r
174 //\r
175 // Calculate Color Map offset in the image.\r
176 //\r
177 Image = BmpImage;\r
178 BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));\r
179\r
180 //\r
181 // Calculate graphics image data address in the image\r
182 //\r
183 Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;\r
184 ImageHeader = Image;\r
185\r
406adcd1 186 BltBufferSize = BmpHeader->PixelWidth * BmpHeader->PixelHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
d4f397c0 187 IsAllocated = FALSE;\r
406adcd1 188 if (*GopBlt == NULL) {\r
189 *GopBltSize = BltBufferSize;\r
190 *GopBlt = AllocatePool (*GopBltSize);\r
191 IsAllocated = TRUE;\r
192 if (*GopBlt == NULL) {\r
878ddf1f 193 return EFI_OUT_OF_RESOURCES;\r
194 }\r
195 } else {\r
406adcd1 196 if (*GopBltSize < BltBufferSize) {\r
197 *GopBltSize = BltBufferSize;\r
878ddf1f 198 return EFI_BUFFER_TOO_SMALL;\r
199 }\r
200 }\r
201\r
202 *PixelWidth = BmpHeader->PixelWidth;\r
203 *PixelHeight = BmpHeader->PixelHeight;\r
204\r
205 //\r
206 // Convert image from BMP to Blt buffer format\r
207 //\r
406adcd1 208 BltBuffer = *GopBlt;\r
878ddf1f 209 for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {\r
210 Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];\r
211 for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {\r
212 switch (BmpHeader->BitPerPixel) {\r
213 case 1:\r
214 //\r
215 // Convert 1bit BMP to 24-bit color\r
216 //\r
217 for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {\r
218 Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;\r
219 Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;\r
220 Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;\r
221 Blt++;\r
222 Width++;\r
223 }\r
224\r
225 Blt --;\r
226 Width --;\r
227 break;\r
228 \r
229 case 4:\r
230 //\r
231 // Convert BMP Palette to 24-bit color\r
232 //\r
233 Index = (*Image) >> 4;\r
234 Blt->Red = BmpColorMap[Index].Red;\r
235 Blt->Green = BmpColorMap[Index].Green;\r
236 Blt->Blue = BmpColorMap[Index].Blue;\r
237 if (Width < (BmpHeader->PixelWidth - 1)) {\r
238 Blt++;\r
239 Width++;\r
240 Index = (*Image) & 0x0f;\r
241 Blt->Red = BmpColorMap[Index].Red;\r
242 Blt->Green = BmpColorMap[Index].Green;\r
243 Blt->Blue = BmpColorMap[Index].Blue;\r
244 }\r
245 break;\r
246\r
247 case 8:\r
248 //\r
249 // Convert BMP Palette to 24-bit color\r
250 //\r
251 Blt->Red = BmpColorMap[*Image].Red;\r
252 Blt->Green = BmpColorMap[*Image].Green;\r
253 Blt->Blue = BmpColorMap[*Image].Blue;\r
254 break;\r
255\r
256 case 24:\r
257 Blt->Blue = *Image++;\r
258 Blt->Green = *Image++;\r
259 Blt->Red = *Image;\r
260 break;\r
261\r
262 default:\r
d4f397c0 263 if (IsAllocated) {\r
406adcd1 264 gBS->FreePool (*GopBlt);\r
265 *GopBlt = NULL;\r
d4f397c0 266 }\r
878ddf1f 267 return EFI_UNSUPPORTED;\r
268 break;\r
269 };\r
270\r
271 }\r
272\r
273 ImageIndex = (UINTN) (Image - ImageHeader);\r
274 if ((ImageIndex % 4) != 0) {\r
275 //\r
276 // Bmp Image starts each row on a 32-bit boundary!\r
277 //\r
278 Image = Image + (4 - (ImageIndex % 4));\r
279 }\r
280 }\r
281\r
282 return EFI_SUCCESS;\r
283}\r
284\r
285\r
286EFI_STATUS\r
287LockKeyboards (\r
288 IN CHAR16 *Password\r
289 )\r
290/*++\r
291\r
292Routine Description:\r
293 Use Console Control Protocol to lock the Console In Spliter virtual handle. \r
294 This is the ConInHandle and ConIn handle in the EFI system table. All key\r
295 presses will be ignored until the Password is typed in. The only way to\r
296 disable the password is to type it in to a ConIn device.\r
297\r
298Arguments:\r
299 Password - Password used to lock ConIn device\r
300\r
301\r
302Returns: \r
303\r
304 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo\r
305 displayed.\r
306 EFI_UNSUPPORTED - Logo not found\r
307\r
308--*/\r
309{\r
310 EFI_STATUS Status;\r
311 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
312\r
313 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
314 if (EFI_ERROR (Status)) {\r
315 return EFI_UNSUPPORTED;\r
316 }\r
317\r
318 Status = ConsoleControl->LockStdIn (ConsoleControl, Password);\r
319 return Status;\r
320}\r
321\r
322\r
323EFI_STATUS\r
324EnableQuietBoot (\r
325 IN EFI_GUID *LogoFile\r
326 )\r
327/*++\r
328\r
329Routine Description:\r
330\r
331 Use Console Control to turn off UGA based Simple Text Out consoles from going\r
332 to the UGA device. Put up LogoFile on every UGA device that is a console\r
333\r
334Arguments:\r
335\r
336 LogoFile - File name of logo to display on the center of the screen.\r
337\r
338\r
339Returns: \r
340\r
341 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo\r
342 displayed.\r
343 EFI_UNSUPPORTED - Logo not found\r
344\r
345--*/\r
346{\r
347 EFI_STATUS Status;\r
348 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
878ddf1f 349 EFI_OEM_BADGING_PROTOCOL *Badging;\r
350 UINT32 SizeOfX;\r
351 UINT32 SizeOfY;\r
878ddf1f 352 INTN DestX;\r
353 INTN DestY;\r
878ddf1f 354 UINT8 *ImageData;\r
355 UINTN ImageSize;\r
406adcd1 356 UINTN BltSize;\r
878ddf1f 357 UINT32 Instance;\r
358 EFI_BADGING_FORMAT Format;\r
359 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;\r
360 UINTN CoordinateX;\r
361 UINTN CoordinateY;\r
362 UINTN Height;\r
363 UINTN Width;\r
406adcd1 364 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
365 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
366 UINT32 ColorDepth;\r
367 UINT32 RefreshRate;\r
368 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
878ddf1f 369\r
370 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
371 if (EFI_ERROR (Status)) {\r
372 return EFI_UNSUPPORTED;\r
373 }\r
374\r
406adcd1 375 UgaDraw = NULL;\r
376 //\r
377 // Try to open GOP first\r
378 //\r
379 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput); \r
380 if (EFI_ERROR(Status)) {\r
381 GraphicsOutput = NULL;\r
382 //\r
383 // Open GOP failed, try to open UGA\r
384 //\r
385 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);\r
386 if (EFI_ERROR (Status)) {\r
387 return EFI_UNSUPPORTED;\r
388 }\r
878ddf1f 389 }\r
390\r
391 Badging = NULL;\r
392 Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);\r
393\r
394 ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics);\r
395\r
406adcd1 396 if (GraphicsOutput != NULL) {\r
397 SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
398 SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
399 } else {\r
400 Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);\r
401 if (EFI_ERROR (Status)) {\r
402 return EFI_UNSUPPORTED;\r
403 }\r
878ddf1f 404 }\r
405\r
406 Instance = 0;\r
407 while (1) {\r
408 ImageData = NULL;\r
409 ImageSize = 0;\r
410\r
411 if (Badging != NULL) {\r
412 Status = Badging->GetImage (\r
413 Badging,\r
414 &Instance,\r
415 &Format,\r
416 &ImageData,\r
417 &ImageSize,\r
418 &Attribute,\r
419 &CoordinateX,\r
420 &CoordinateY\r
421 );\r
422 if (EFI_ERROR (Status)) {\r
423 return Status;\r
424 }\r
425\r
426 //\r
427 // Currently only support BMP format\r
428 //\r
429 if (Format != EfiBadgingFormatBMP) {\r
430 gBS->FreePool (ImageData);\r
431 continue;\r
432 }\r
433 } else {\r
434 Status = GetGraphicsBitMapFromFV (LogoFile, (VOID **) &ImageData, &ImageSize);\r
435 if (EFI_ERROR (Status)) {\r
436 return EFI_UNSUPPORTED;\r
437 }\r
438\r
439 CoordinateX = 0;\r
440 CoordinateY = 0;\r
441 Attribute = EfiBadgingDisplayAttributeCenter;\r
442 }\r
443\r
406adcd1 444 Blt = NULL;\r
617de480 445 BltSize = 0;\r
406adcd1 446 Status = ConvertBmpToGopBlt (\r
878ddf1f 447 ImageData,\r
448 ImageSize,\r
406adcd1 449 (VOID**)&Blt,\r
450 &BltSize,\r
878ddf1f 451 &Height,\r
452 &Width\r
453 );\r
454 if (EFI_ERROR (Status)) {\r
455 gBS->FreePool (ImageData);\r
406adcd1 456 if (Badging == NULL) {\r
457 return Status;\r
458 } else {\r
459 continue;\r
460 }\r
878ddf1f 461 }\r
462\r
463 switch (Attribute) {\r
464 case EfiBadgingDisplayAttributeLeftTop:\r
465 DestX = CoordinateX;\r
466 DestY = CoordinateY;\r
467 break;\r
468\r
469 case EfiBadgingDisplayAttributeCenterTop:\r
470 DestX = (SizeOfX - Width) / 2;\r
471 DestY = CoordinateY;\r
472 break;\r
473\r
474 case EfiBadgingDisplayAttributeRightTop:\r
475 DestX = (SizeOfX - Width - CoordinateX);\r
476 DestY = CoordinateY;;\r
477 break;\r
478\r
479 case EfiBadgingDisplayAttributeCenterRight:\r
480 DestX = (SizeOfX - Width - CoordinateX);\r
481 DestY = (SizeOfY - Height) / 2;\r
482 break;\r
483\r
484 case EfiBadgingDisplayAttributeRightBottom:\r
485 DestX = (SizeOfX - Width - CoordinateX);\r
486 DestY = (SizeOfY - Height - CoordinateY);\r
487 break;\r
488\r
489 case EfiBadgingDisplayAttributeCenterBottom:\r
490 DestX = (SizeOfX - Width) / 2;\r
491 DestY = (SizeOfY - Height - CoordinateY);\r
492 break;\r
493\r
494 case EfiBadgingDisplayAttributeLeftBottom:\r
495 DestX = CoordinateX;\r
496 DestY = (SizeOfY - Height - CoordinateY);\r
497 break;\r
498\r
499 case EfiBadgingDisplayAttributeCenterLeft:\r
500 DestX = CoordinateX;\r
501 DestY = (SizeOfY - Height) / 2;\r
502 break;\r
503\r
504 case EfiBadgingDisplayAttributeCenter:\r
505 DestX = (SizeOfX - Width) / 2;\r
506 DestY = (SizeOfY - Height) / 2;\r
507 break;\r
508\r
509 default:\r
510 DestX = CoordinateX;\r
511 DestY = CoordinateY;\r
512 break;\r
513 }\r
514\r
515 if ((DestX >= 0) && (DestY >= 0)) {\r
406adcd1 516 if (GraphicsOutput != NULL) {\r
517 Status = GraphicsOutput->Blt (\r
518 GraphicsOutput,\r
519 Blt,\r
520 EfiBltBufferToVideo,\r
521 0,\r
522 0,\r
523 (UINTN) DestX,\r
524 (UINTN) DestY,\r
525 Width,\r
526 Height,\r
527 Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
528 );\r
529 } else {\r
530 Status = UgaDraw->Blt (\r
531 UgaDraw,\r
532 (EFI_UGA_PIXEL *) Blt,\r
533 EfiUgaBltBufferToVideo,\r
534 0,\r
535 0,\r
536 (UINTN) DestX,\r
537 (UINTN) DestY,\r
538 Width,\r
539 Height,\r
540 Width * sizeof (EFI_UGA_PIXEL)\r
541 );\r
542 }\r
878ddf1f 543 }\r
544\r
545 gBS->FreePool (ImageData);\r
406adcd1 546 gBS->FreePool (Blt);\r
878ddf1f 547\r
548 if (Badging == NULL) {\r
549 break;\r
550 }\r
551 }\r
552\r
553 return Status;\r
554}\r
555\r
556\r
557EFI_STATUS\r
558DisableQuietBoot (\r
559 VOID\r
560 )\r
561/*++\r
562\r
563Routine Description:\r
564\r
565 Use Console Control to turn on UGA based Simple Text Out consoles. The UGA \r
566 Simple Text Out screens will now be synced up with all non UGA output devices\r
567\r
568Arguments:\r
569\r
570 NONE\r
571\r
572Returns: \r
573\r
574 EFI_SUCCESS - UGA devices are back in text mode and synced up.\r
575 EFI_UNSUPPORTED - Logo not found\r
576\r
577--*/\r
578{\r
579 EFI_STATUS Status;\r
580 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
581\r
582 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
583 if (EFI_ERROR (Status)) {\r
584 return EFI_UNSUPPORTED;\r
585 }\r
586\r
587 return ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);\r
588}\r
589\r
406adcd1 590static EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors[16] = {\r
878ddf1f 591 { 0x00, 0x00, 0x00, 0x00 },\r
592 { 0x98, 0x00, 0x00, 0x00 },\r
593 { 0x00, 0x98, 0x00, 0x00 },\r
594 { 0x98, 0x98, 0x00, 0x00 },\r
595 { 0x00, 0x00, 0x98, 0x00 },\r
596 { 0x98, 0x00, 0x98, 0x00 },\r
597 { 0x00, 0x98, 0x98, 0x00 },\r
598 { 0x98, 0x98, 0x98, 0x00 },\r
599 { 0x10, 0x10, 0x10, 0x00 },\r
600 { 0xff, 0x10, 0x10, 0x00 },\r
601 { 0x10, 0xff, 0x10, 0x00 },\r
602 { 0xff, 0xff, 0x10, 0x00 },\r
603 { 0x10, 0x10, 0xff, 0x00 },\r
604 { 0xf0, 0x10, 0xff, 0x00 },\r
605 { 0x10, 0xff, 0xff, 0x00 },\r
606 { 0xff, 0xff, 0xff, 0x00 }\r
607};\r
608\r
609STATIC\r
610UINTN\r
611_IPrint (\r
406adcd1 612 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
878ddf1f 613 IN EFI_UGA_DRAW_PROTOCOL *UgaDraw,\r
614 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *Sto,\r
615 IN UINTN X,\r
616 IN UINTN Y,\r
406adcd1 617 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,\r
618 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background,\r
878ddf1f 619 IN CHAR16 *fmt,\r
620 IN VA_LIST args\r
621 )\r
622/*++\r
623\r
624Routine Description:\r
625\r
626 Display string worker for: Print, PrintAt, IPrint, IPrintAt\r
627\r
628Arguments:\r
629\r
406adcd1 630 GraphicsOutput - Graphics output protocol interface\r
631 \r
878ddf1f 632 UgaDraw - UGA draw protocol interface\r
633 \r
634 Sto - Simple text out protocol interface\r
635 \r
636 X - X coordinate to start printing\r
637 \r
638 Y - Y coordinate to start printing\r
639 \r
640 Foreground - Foreground color\r
641 \r
642 Background - Background color\r
643 \r
644 fmt - Format string\r
645 \r
646 args - Print arguments\r
647\r
648Returns: \r
649\r
650 EFI_SUCCESS - success\r
651 EFI_OUT_OF_RESOURCES - out of resources\r
652\r
653--*/\r
654{\r
655 VOID *Buffer;\r
656 EFI_STATUS Status;\r
657 UINT16 GlyphWidth;\r
658 UINT32 GlyphStatus;\r
659 UINT16 StringIndex;\r
660 UINTN Index;\r
661 CHAR16 *UnicodeWeight;\r
662 EFI_NARROW_GLYPH *Glyph;\r
663 EFI_HII_PROTOCOL *Hii;\r
406adcd1 664 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LineBuffer;\r
878ddf1f 665 UINT32 HorizontalResolution;\r
666 UINT32 VerticalResolution;\r
667 UINT32 ColorDepth;\r
668 UINT32 RefreshRate;\r
1cc8ee78 669 UINTN BufferGlyphWidth;\r
878ddf1f 670\r
671 GlyphStatus = 0;\r
672\r
673 //\r
674 // For now, allocate an arbitrarily long buffer\r
675 //\r
676 Buffer = AllocateZeroPool (0x10000);\r
677 if (Buffer == NULL) {\r
678 return EFI_OUT_OF_RESOURCES;\r
679 }\r
406adcd1 680 \r
681 if (GraphicsOutput != NULL) {\r
682 HorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;\r
683 VerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;\r
684 } else {\r
685 //\r
686 // Get the current mode information from the UGA Draw Protocol\r
687 //\r
688 UgaDraw->GetMode (UgaDraw, &HorizontalResolution, &VerticalResolution, &ColorDepth, &RefreshRate);\r
689 }\r
878ddf1f 690\r
406adcd1 691 LineBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * HorizontalResolution * GLYPH_WIDTH * GLYPH_HEIGHT);\r
878ddf1f 692 if (LineBuffer == NULL) {\r
693 gBS->FreePool (Buffer);\r
694 return EFI_OUT_OF_RESOURCES;\r
695 }\r
696\r
697 Status = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, (VOID **) &Hii);\r
698 if (EFI_ERROR (Status)) {\r
699 goto Error;\r
700 }\r
701\r
702 UnicodeVSPrint (Buffer, 0x10000, fmt, args);\r
703\r
704 UnicodeWeight = (CHAR16 *) Buffer;\r
705\r
706 for (Index = 0; UnicodeWeight[Index] != 0; Index++) {\r
707 if (UnicodeWeight[Index] == CHAR_BACKSPACE ||\r
708 UnicodeWeight[Index] == CHAR_LINEFEED ||\r
709 UnicodeWeight[Index] == CHAR_CARRIAGE_RETURN) {\r
710 UnicodeWeight[Index] = 0;\r
711 }\r
712 }\r
713\r
714 for (Index = 0; Index < StrLen (Buffer); Index++) {\r
715 StringIndex = (UINT16) Index;\r
716 Status = Hii->GetGlyph (Hii, UnicodeWeight, &StringIndex, (UINT8 **) &Glyph, &GlyphWidth, &GlyphStatus);\r
717 if (EFI_ERROR (Status)) {\r
718 goto Error;\r
719 }\r
720\r
721 if (Foreground == NULL || Background == NULL) {\r
722 Status = Hii->GlyphToBlt (\r
723 Hii,\r
724 (UINT8 *) Glyph,\r
725 mEfiColors[Sto->Mode->Attribute & 0x0f],\r
726 mEfiColors[Sto->Mode->Attribute >> 4],\r
727 StrLen (Buffer),\r
728 GlyphWidth,\r
729 GLYPH_HEIGHT,\r
730 &LineBuffer[Index * GLYPH_WIDTH]\r
731 );\r
732 } else {\r
733 Status = Hii->GlyphToBlt (\r
734 Hii,\r
735 (UINT8 *) Glyph,\r
736 *Foreground,\r
737 *Background,\r
738 StrLen (Buffer),\r
739 GlyphWidth,\r
740 GLYPH_HEIGHT,\r
741 &LineBuffer[Index * GLYPH_WIDTH]\r
742 );\r
743 }\r
744 }\r
745\r
746 //\r
747 // Blt a character to the screen\r
748 //\r
1cc8ee78 749 BufferGlyphWidth = GLYPH_WIDTH * StrLen (Buffer);\r
406adcd1 750 if (GraphicsOutput != NULL) {\r
751 Status = GraphicsOutput->Blt (\r
752 GraphicsOutput,\r
753 LineBuffer,\r
754 EfiBltBufferToVideo,\r
755 0,\r
756 0,\r
757 X,\r
758 Y,\r
1cc8ee78 759 BufferGlyphWidth,\r
406adcd1 760 GLYPH_HEIGHT,\r
1cc8ee78 761 BufferGlyphWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
406adcd1 762 );\r
763 } else {\r
764 Status = UgaDraw->Blt (\r
765 UgaDraw,\r
766 (EFI_UGA_PIXEL *) (UINTN) LineBuffer,\r
767 EfiUgaBltBufferToVideo,\r
768 0,\r
769 0,\r
770 X,\r
771 Y,\r
1cc8ee78 772 BufferGlyphWidth,\r
406adcd1 773 GLYPH_HEIGHT,\r
1cc8ee78 774 BufferGlyphWidth * sizeof (EFI_UGA_PIXEL)\r
406adcd1 775 );\r
776 }\r
878ddf1f 777\r
778Error:\r
779 gBS->FreePool (LineBuffer);\r
780 gBS->FreePool (Buffer);\r
781 return Status;\r
782}\r
783\r
784\r
785UINTN\r
786PrintXY (\r
787 IN UINTN X,\r
788 IN UINTN Y,\r
406adcd1 789 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ForeGround, OPTIONAL\r
790 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BackGround, OPTIONAL\r
878ddf1f 791 IN CHAR16 *Fmt,\r
792 ...\r
793 )\r
794/*++\r
795\r
796Routine Description:\r
797\r
798 Prints a formatted unicode string to the default console\r
799\r
800Arguments:\r
801\r
802 X - X coordinate to start printing\r
803 \r
804 Y - Y coordinate to start printing\r
805 \r
806 ForeGround - Foreground color\r
807 \r
808 BackGround - Background color\r
809\r
810 Fmt - Format string\r
811\r
812 ... - Print arguments\r
813\r
814Returns:\r
815\r
816 Length of string printed to the console\r
817\r
818--*/\r
819{\r
820 EFI_HANDLE Handle;\r
406adcd1 821\r
822 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
878ddf1f 823 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
824 EFI_SIMPLE_TEXT_OUT_PROTOCOL *Sto;\r
825 EFI_STATUS Status;\r
826 VA_LIST Args;\r
827\r
828 VA_START (Args, Fmt);\r
829\r
406adcd1 830 UgaDraw = NULL;\r
831\r
878ddf1f 832 Handle = gST->ConsoleOutHandle;\r
833\r
834 Status = gBS->HandleProtocol (\r
835 Handle,\r
406adcd1 836 &gEfiGraphicsOutputProtocolGuid,\r
837 (VOID **) &GraphicsOutput\r
878ddf1f 838 );\r
839\r
840 if (EFI_ERROR (Status)) {\r
406adcd1 841 GraphicsOutput = NULL;\r
842\r
843 Status = gBS->HandleProtocol (\r
844 Handle,\r
845 &gEfiUgaDrawProtocolGuid,\r
846 (VOID **) &UgaDraw\r
847 );\r
848\r
849 if (EFI_ERROR (Status)) {\r
850 return Status;\r
851 }\r
878ddf1f 852 }\r
853\r
854 Status = gBS->HandleProtocol (\r
855 Handle,\r
856 &gEfiSimpleTextOutProtocolGuid,\r
857 (VOID **) &Sto\r
858 );\r
859\r
860 if (EFI_ERROR (Status)) {\r
861 return Status;\r
862 }\r
863\r
406adcd1 864 return _IPrint (GraphicsOutput, UgaDraw, Sto, X, Y, ForeGround, BackGround, Fmt, Args);\r
878ddf1f 865}\r