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