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