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