]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Library/GraphicsLib/Graphics.c
Fixed a typo in variable name
[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
695f7e98 418 } else {\r
419 return EFI_UNSUPPORTED;\r
45e6322c 420 }\r
421\r
422 Instance = 0;\r
423 while (1) {\r
424 ImageData = NULL;\r
425 ImageSize = 0;\r
426\r
427 if (Badging != NULL) {\r
428 Status = Badging->GetImage (\r
429 Badging,\r
430 &Instance,\r
431 &Format,\r
432 &ImageData,\r
433 &ImageSize,\r
434 &Attribute,\r
435 &CoordinateX,\r
436 &CoordinateY\r
437 );\r
438 if (EFI_ERROR (Status)) {\r
439 return Status;\r
440 }\r
441\r
442 //\r
443 // Currently only support BMP format\r
444 //\r
445 if (Format != EfiBadgingFormatBMP) {\r
446 gBS->FreePool (ImageData);\r
447 continue;\r
448 }\r
449 } else {\r
450 Status = GetGraphicsBitMapFromFV (LogoFile, (VOID **) &ImageData, &ImageSize);\r
451 if (EFI_ERROR (Status)) {\r
452 return EFI_UNSUPPORTED;\r
453 }\r
454\r
455 CoordinateX = 0;\r
456 CoordinateY = 0;\r
457 Attribute = EfiBadgingDisplayAttributeCenter;\r
458 }\r
459\r
460 Blt = NULL;\r
461 BltSize = 0;\r
462 Status = ConvertBmpToGopBlt (\r
463 ImageData,\r
464 ImageSize,\r
465 (VOID**)&Blt,\r
466 &BltSize,\r
467 &Height,\r
468 &Width\r
469 );\r
470 if (EFI_ERROR (Status)) {\r
471 gBS->FreePool (ImageData);\r
472 if (Badging == NULL) {\r
473 return Status;\r
474 } else {\r
475 continue;\r
476 }\r
477 }\r
478\r
479 switch (Attribute) {\r
480 case EfiBadgingDisplayAttributeLeftTop:\r
481 DestX = CoordinateX;\r
482 DestY = CoordinateY;\r
483 break;\r
484\r
485 case EfiBadgingDisplayAttributeCenterTop:\r
486 DestX = (SizeOfX - Width) / 2;\r
487 DestY = CoordinateY;\r
488 break;\r
489\r
490 case EfiBadgingDisplayAttributeRightTop:\r
491 DestX = (SizeOfX - Width - CoordinateX);\r
492 DestY = CoordinateY;;\r
493 break;\r
494\r
495 case EfiBadgingDisplayAttributeCenterRight:\r
496 DestX = (SizeOfX - Width - CoordinateX);\r
497 DestY = (SizeOfY - Height) / 2;\r
498 break;\r
499\r
500 case EfiBadgingDisplayAttributeRightBottom:\r
501 DestX = (SizeOfX - Width - CoordinateX);\r
502 DestY = (SizeOfY - Height - CoordinateY);\r
503 break;\r
504\r
505 case EfiBadgingDisplayAttributeCenterBottom:\r
506 DestX = (SizeOfX - Width) / 2;\r
507 DestY = (SizeOfY - Height - CoordinateY);\r
508 break;\r
509\r
510 case EfiBadgingDisplayAttributeLeftBottom:\r
511 DestX = CoordinateX;\r
512 DestY = (SizeOfY - Height - CoordinateY);\r
513 break;\r
514\r
515 case EfiBadgingDisplayAttributeCenterLeft:\r
516 DestX = CoordinateX;\r
517 DestY = (SizeOfY - Height) / 2;\r
518 break;\r
519\r
520 case EfiBadgingDisplayAttributeCenter:\r
521 DestX = (SizeOfX - Width) / 2;\r
522 DestY = (SizeOfY - Height) / 2;\r
523 break;\r
524\r
525 default:\r
526 DestX = CoordinateX;\r
527 DestY = CoordinateY;\r
528 break;\r
529 }\r
530\r
531 if ((DestX >= 0) && (DestY >= 0)) {\r
532 if (GraphicsOutput != NULL) {\r
533 Status = GraphicsOutput->Blt (\r
534 GraphicsOutput,\r
535 Blt,\r
536 EfiBltBufferToVideo,\r
537 0,\r
538 0,\r
539 (UINTN) DestX,\r
540 (UINTN) DestY,\r
541 Width,\r
542 Height,\r
543 Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
544 );\r
8541adab 545 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
45e6322c 546 Status = UgaDraw->Blt (\r
547 UgaDraw,\r
548 (EFI_UGA_PIXEL *) Blt,\r
549 EfiUgaBltBufferToVideo,\r
550 0,\r
551 0,\r
552 (UINTN) DestX,\r
553 (UINTN) DestY,\r
554 Width,\r
555 Height,\r
556 Width * sizeof (EFI_UGA_PIXEL)\r
557 );\r
8541adab 558 } else {\r
559 Status = EFI_UNSUPPORTED;\r
45e6322c 560 }\r
561 }\r
562\r
563 gBS->FreePool (ImageData);\r
564 gBS->FreePool (Blt);\r
565\r
566 if (Badging == NULL) {\r
567 break;\r
568 }\r
569 }\r
570\r
571 return Status;\r
572}\r
573\r
574\r
575EFI_STATUS\r
576DisableQuietBoot (\r
577 VOID\r
578 )\r
579/*++\r
580\r
581Routine Description:\r
582\r
62409219 583 Use Console Control to turn on GOP/UGA based Simple Text Out consoles. The GOP/UGA\r
584 Simple Text Out screens will now be synced up with all non GOP/UGA output devices\r
45e6322c 585\r
586Arguments:\r
587\r
588 NONE\r
589\r
67996c41 590Returns:\r
45e6322c 591\r
62409219 592 EFI_SUCCESS - GOP/UGA devices are back in text mode and synced up.\r
45e6322c 593 EFI_UNSUPPORTED - Logo not found\r
594\r
595--*/\r
596{\r
597 EFI_STATUS Status;\r
598 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
599\r
600 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
601 if (EFI_ERROR (Status)) {\r
602 return EFI_UNSUPPORTED;\r
603 }\r
604\r
605 return ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);\r
606}\r
607\r
608static EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors[16] = {\r
609 { 0x00, 0x00, 0x00, 0x00 },\r
610 { 0x98, 0x00, 0x00, 0x00 },\r
611 { 0x00, 0x98, 0x00, 0x00 },\r
612 { 0x98, 0x98, 0x00, 0x00 },\r
613 { 0x00, 0x00, 0x98, 0x00 },\r
614 { 0x98, 0x00, 0x98, 0x00 },\r
615 { 0x00, 0x98, 0x98, 0x00 },\r
616 { 0x98, 0x98, 0x98, 0x00 },\r
617 { 0x10, 0x10, 0x10, 0x00 },\r
618 { 0xff, 0x10, 0x10, 0x00 },\r
619 { 0x10, 0xff, 0x10, 0x00 },\r
620 { 0xff, 0xff, 0x10, 0x00 },\r
621 { 0x10, 0x10, 0xff, 0x00 },\r
622 { 0xf0, 0x10, 0xff, 0x00 },\r
623 { 0x10, 0xff, 0xff, 0x00 },\r
624 { 0xff, 0xff, 0xff, 0x00 }\r
625};\r
626\r
627STATIC\r
628UINTN\r
629_IPrint (\r
630 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
631 IN EFI_UGA_DRAW_PROTOCOL *UgaDraw,\r
632 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Sto,\r
633 IN UINTN X,\r
634 IN UINTN Y,\r
635 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,\r
636 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background,\r
637 IN CHAR16 *fmt,\r
638 IN VA_LIST args\r
639 )\r
640/*++\r
641\r
642Routine Description:\r
643\r
644 Display string worker for: Print, PrintAt, IPrint, IPrintAt\r
645\r
646Arguments:\r
647\r
648 GraphicsOutput - Graphics output protocol interface\r
67996c41 649\r
45e6322c 650 UgaDraw - UGA draw protocol interface\r
67996c41 651\r
45e6322c 652 Sto - Simple text out protocol interface\r
67996c41 653\r
45e6322c 654 X - X coordinate to start printing\r
67996c41 655\r
45e6322c 656 Y - Y coordinate to start printing\r
67996c41 657\r
45e6322c 658 Foreground - Foreground color\r
67996c41 659\r
45e6322c 660 Background - Background color\r
67996c41 661\r
45e6322c 662 fmt - Format string\r
67996c41 663\r
45e6322c 664 args - Print arguments\r
665\r
67996c41 666Returns:\r
45e6322c 667\r
668 EFI_SUCCESS - success\r
669 EFI_OUT_OF_RESOURCES - out of resources\r
670\r
671--*/\r
672{\r
62409219 673 VOID *Buffer;\r
674 EFI_STATUS Status;\r
675 UINT16 GlyphWidth;\r
676 UINT32 GlyphStatus;\r
677 UINT16 StringIndex;\r
678 UINTN Index;\r
679 CHAR16 *UnicodeWeight;\r
680 EFI_NARROW_GLYPH *Glyph;\r
681 EFI_HII_PROTOCOL *Hii;\r
682 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LineBuffer;\r
683 UINT32 HorizontalResolution;\r
684 UINT32 VerticalResolution;\r
685 UINT32 ColorDepth;\r
686 UINT32 RefreshRate;\r
687 UINTN BufferLen;\r
688 UINTN LineBufferLen;\r
689 UINTN BufferGlyphWidth;\r
45e6322c 690\r
691 GlyphStatus = 0;\r
692\r
693 //\r
694 // For now, allocate an arbitrarily long buffer\r
695 //\r
696 Buffer = AllocateZeroPool (0x10000);\r
697 if (Buffer == NULL) {\r
698 return EFI_OUT_OF_RESOURCES;\r
699 }\r
67996c41 700\r
45e6322c 701 if (GraphicsOutput != NULL) {\r
702 HorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;\r
703 VerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;\r
8541adab 704 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
45e6322c 705 //\r
706 // Get the current mode information from the UGA Draw Protocol\r
707 //\r
708 UgaDraw->GetMode (UgaDraw, &HorizontalResolution, &VerticalResolution, &ColorDepth, &RefreshRate);\r
709 }\r
62409219 710 ASSERT ((HorizontalResolution != 0) && (VerticalResolution !=0));\r
45e6322c 711\r
62409219 712 LineBufferLen = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * HorizontalResolution * GLYPH_HEIGHT;\r
713 LineBuffer = AllocatePool (LineBufferLen);\r
45e6322c 714 if (LineBuffer == NULL) {\r
715 gBS->FreePool (Buffer);\r
716 return EFI_OUT_OF_RESOURCES;\r
717 }\r
718\r
719 Status = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, (VOID **) &Hii);\r
720 if (EFI_ERROR (Status)) {\r
721 goto Error;\r
722 }\r
723\r
724 UnicodeVSPrint (Buffer, 0x10000, fmt, args);\r
725\r
726 UnicodeWeight = (CHAR16 *) Buffer;\r
727\r
728 for (Index = 0; UnicodeWeight[Index] != 0; Index++) {\r
729 if (UnicodeWeight[Index] == CHAR_BACKSPACE ||\r
730 UnicodeWeight[Index] == CHAR_LINEFEED ||\r
731 UnicodeWeight[Index] == CHAR_CARRIAGE_RETURN) {\r
732 UnicodeWeight[Index] = 0;\r
733 }\r
734 }\r
735\r
62409219 736 BufferLen = StrLen (Buffer);\r
737\r
738 if (GLYPH_WIDTH * GLYPH_HEIGHT * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * BufferLen > LineBufferLen) {\r
739 Status = EFI_INVALID_PARAMETER;\r
740 goto Error;\r
741 }\r
742\r
743 for (Index = 0; Index < BufferLen; Index++) {\r
45e6322c 744 StringIndex = (UINT16) Index;\r
745 Status = Hii->GetGlyph (Hii, UnicodeWeight, &StringIndex, (UINT8 **) &Glyph, &GlyphWidth, &GlyphStatus);\r
746 if (EFI_ERROR (Status)) {\r
747 goto Error;\r
748 }\r
749\r
750 if (Foreground == NULL || Background == NULL) {\r
751 Status = Hii->GlyphToBlt (\r
752 Hii,\r
753 (UINT8 *) Glyph,\r
754 mEfiColors[Sto->Mode->Attribute & 0x0f],\r
755 mEfiColors[Sto->Mode->Attribute >> 4],\r
62409219 756 BufferLen,\r
45e6322c 757 GlyphWidth,\r
758 GLYPH_HEIGHT,\r
759 &LineBuffer[Index * GLYPH_WIDTH]\r
760 );\r
761 } else {\r
762 Status = Hii->GlyphToBlt (\r
763 Hii,\r
764 (UINT8 *) Glyph,\r
765 *Foreground,\r
766 *Background,\r
62409219 767 BufferLen,\r
45e6322c 768 GlyphWidth,\r
769 GLYPH_HEIGHT,\r
770 &LineBuffer[Index * GLYPH_WIDTH]\r
771 );\r
772 }\r
773 }\r
774\r
775 //\r
776 // Blt a character to the screen\r
777 //\r
62409219 778 BufferGlyphWidth = GLYPH_WIDTH * BufferLen;\r
45e6322c 779 if (GraphicsOutput != NULL) {\r
780 Status = GraphicsOutput->Blt (\r
781 GraphicsOutput,\r
782 LineBuffer,\r
783 EfiBltBufferToVideo,\r
784 0,\r
785 0,\r
786 X,\r
787 Y,\r
788 BufferGlyphWidth,\r
789 GLYPH_HEIGHT,\r
790 BufferGlyphWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
791 );\r
8541adab 792 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
45e6322c 793 Status = UgaDraw->Blt (\r
794 UgaDraw,\r
795 (EFI_UGA_PIXEL *) (UINTN) LineBuffer,\r
796 EfiUgaBltBufferToVideo,\r
797 0,\r
798 0,\r
799 X,\r
800 Y,\r
801 BufferGlyphWidth,\r
802 GLYPH_HEIGHT,\r
803 BufferGlyphWidth * sizeof (EFI_UGA_PIXEL)\r
804 );\r
8541adab 805 } else {\r
806 Status = EFI_UNSUPPORTED;\r
45e6322c 807 }\r
808\r
809Error:\r
810 gBS->FreePool (LineBuffer);\r
811 gBS->FreePool (Buffer);\r
812 return Status;\r
813}\r
814\r
815\r
816UINTN\r
817PrintXY (\r
818 IN UINTN X,\r
819 IN UINTN Y,\r
820 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ForeGround, OPTIONAL\r
821 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BackGround, OPTIONAL\r
822 IN CHAR16 *Fmt,\r
823 ...\r
824 )\r
825/*++\r
826\r
827Routine Description:\r
828\r
829 Prints a formatted unicode string to the default console\r
830\r
831Arguments:\r
832\r
833 X - X coordinate to start printing\r
67996c41 834\r
45e6322c 835 Y - Y coordinate to start printing\r
67996c41 836\r
45e6322c 837 ForeGround - Foreground color\r
67996c41 838\r
45e6322c 839 BackGround - Background color\r
840\r
841 Fmt - Format string\r
842\r
843 ... - Print arguments\r
844\r
845Returns:\r
846\r
847 Length of string printed to the console\r
848\r
849--*/\r
850{\r
851 EFI_HANDLE Handle;\r
852\r
853 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
854 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
855 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Sto;\r
856 EFI_STATUS Status;\r
857 VA_LIST Args;\r
858\r
859 VA_START (Args, Fmt);\r
860\r
861 UgaDraw = NULL;\r
862\r
863 Handle = gST->ConsoleOutHandle;\r
864\r
865 Status = gBS->HandleProtocol (\r
866 Handle,\r
867 &gEfiGraphicsOutputProtocolGuid,\r
868 (VOID **) &GraphicsOutput\r
869 );\r
870\r
8541adab 871 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
45e6322c 872 GraphicsOutput = NULL;\r
873\r
874 Status = gBS->HandleProtocol (\r
875 Handle,\r
876 &gEfiUgaDrawProtocolGuid,\r
877 (VOID **) &UgaDraw\r
878 );\r
8541adab 879 }\r
45e6322c 880\r
8541adab 881 if (EFI_ERROR (Status)) {\r
882 return Status;\r
45e6322c 883 }\r
884\r
885 Status = gBS->HandleProtocol (\r
886 Handle,\r
887 &gEfiSimpleTextOutProtocolGuid,\r
888 (VOID **) &Sto\r
889 );\r
890\r
891 if (EFI_ERROR (Status)) {\r
892 return Status;\r
893 }\r
894\r
895 return _IPrint (GraphicsOutput, UgaDraw, Sto, X, Y, ForeGround, BackGround, Fmt, Args);\r
896}\r