]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/GraphicsLib/Graphics.c
Remove SafeFreePool from MemoryAllocationLib as this API's name is misleading. Its...
[mirror_edk2.git] / MdeModulePkg / Library / GraphicsLib / Graphics.c
CommitLineData
677472aa 1/** @file\r
2 Library supports diplaying graphical splash screen,\r
3 locking of keyboard input and printing character on\r
4 screen. These basic graphics operations are based on UEFI HII, \r
5 Graphics Output protocol or UGA Draw protocol.\r
6\r
7Copyright (c) 2006 - 2008, Intel Corporation\r
8All rights reserved. This program and the accompanying materials\r
9are licensed and made available under the terms and conditions of the BSD License\r
10which accompanies this distribution. The full text of the license may be found at\r
11http://opensource.org/licenses/bsd-license.php\r
12\r
13THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15\r
16**/\r
17\r
18\r
19#include <PiDxe.h>\r
20\r
21#include <Protocol/SimpleTextOut.h>\r
22#include <Protocol/OEMBadging.h>\r
23#include <Protocol/ConsoleControl.h>\r
24#include <Protocol/GraphicsOutput.h>\r
25#include <Protocol/UgaDraw.h>\r
26#include <Protocol/HiiFont.h>\r
27#include <Protocol/HiiImage.h>\r
28\r
29#include <Guid/Bmp.h>\r
30\r
31#include <Library/GraphicsLib.h>\r
32#include <Library/PrintLib.h>\r
33#include <Library/BaseLib.h>\r
34#include <Library/MemoryAllocationLib.h>\r
35#include <Library/UefiBootServicesTableLib.h>\r
36#include <Library/DebugLib.h>\r
37#include <Library/BaseMemoryLib.h>\r
38#include <Library/DxePiLib.h>\r
39#include <Library/PcdLib.h>\r
40\r
41STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors[16] = {\r
42 { 0x00, 0x00, 0x00, 0x00 },\r
43 { 0x98, 0x00, 0x00, 0x00 },\r
44 { 0x00, 0x98, 0x00, 0x00 },\r
45 { 0x98, 0x98, 0x00, 0x00 },\r
46 { 0x00, 0x00, 0x98, 0x00 },\r
47 { 0x98, 0x00, 0x98, 0x00 },\r
48 { 0x00, 0x98, 0x98, 0x00 },\r
49 { 0x98, 0x98, 0x98, 0x00 },\r
50 { 0x10, 0x10, 0x10, 0x00 },\r
51 { 0xff, 0x10, 0x10, 0x00 },\r
52 { 0x10, 0xff, 0x10, 0x00 },\r
53 { 0xff, 0xff, 0x10, 0x00 },\r
54 { 0x10, 0x10, 0xff, 0x00 },\r
55 { 0xf0, 0x10, 0xff, 0x00 },\r
56 { 0x10, 0xff, 0xff, 0x00 },\r
57 { 0xff, 0xff, 0xff, 0x00 }\r
58};\r
59\r
60\r
61/**\r
62 Return the graphics image file named FileNameGuid into Image and return it's\r
63 size in ImageSize. All Firmware Volumes (FV) in the system are searched for the\r
64 file name.\r
65\r
66 @param FileNameGuid File Name of graphics file in the FV(s).\r
67 @param Image Pointer to pointer to return graphics image. If NULL, a \r
68 buffer will be allocated.\r
69 @param ImageSize Size of the graphics Image in bytes. Zero if no image found.\r
70\r
71 @retval EFI_SUCCESS Image and ImageSize are valid. \r
72 @retval EFI_BUFFER_TOO_SMALL Image not big enough. ImageSize has required size\r
73 @retval EFI_NOT_FOUND FileNameGuid not found\r
74\r
75**/\r
76EFI_STATUS\r
77EFIAPI\r
78GetGraphicsBitMapFromFV (\r
79 IN EFI_GUID *FileNameGuid,\r
80 OUT VOID **Image,\r
81 OUT UINTN *ImageSize\r
82 )\r
83{\r
84 return GetGraphicsBitMapFromFVEx (NULL, FileNameGuid, Image, ImageSize);\r
85}\r
86\r
87/**\r
88 Return the graphics image file named FileNameGuid into Image and return it's\r
89 size in ImageSize. All Firmware Volumes (FV) in the system are searched for the\r
90 file name.\r
91\r
92 @param ImageHandle The driver image handle of the caller. The parameter is used to\r
93 optimize the loading of the image file so that the FV from which\r
94 the driver image is loaded will be tried first. \r
95 @param FileNameGuid File Name of graphics file in the FV(s).\r
96 @param Image Pointer to pointer to return graphics image. If NULL, a \r
97 buffer will be allocated.\r
98 @param ImageSize Size of the graphics Image in bytes. Zero if no image found.\r
99\r
100 @retval EFI_SUCCESS Image and ImageSize are valid. \r
101 @retval EFI_BUFFER_TOO_SMALL Image not big enough. ImageSize has required size\r
102 @retval EFI_NOT_FOUND FileNameGuid not found\r
103\r
104**/\r
105EFI_STATUS\r
106EFIAPI\r
107GetGraphicsBitMapFromFVEx (\r
108 IN EFI_HANDLE ImageHandle,\r
109 IN EFI_GUID *FileNameGuid,\r
110 OUT VOID **Image,\r
111 OUT UINTN *ImageSize\r
112 )\r
113{\r
114 return PiLibGetSectionFromAnyFv (\r
115 FileNameGuid,\r
116 EFI_SECTION_RAW,\r
117 0,\r
118 Image,\r
119 ImageSize\r
120 );\r
121}\r
122\r
123/**\r
124 Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer\r
125 is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt\r
126 buffer is passed in it will be used if it is big enough.\r
127\r
128 @param BmpImage Pointer to BMP file\r
129 @param BmpImageSize Number of bytes in BmpImage\r
130 @param GopBlt Buffer containing GOP version of BmpImage.\r
131 @param GopBltSize Size of GopBlt in bytes.\r
132 @param PixelHeight Height of GopBlt/BmpImage in pixels\r
133 @param PixelWidth Width of GopBlt/BmpImage in pixels\r
134\r
135 @retval EFI_SUCCESS GopBlt and GopBltSize are returned. \r
136 @retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image\r
137 @retval EFI_BUFFER_TOO_SMALL The passed in GopBlt buffer is not big enough.\r
138 GopBltSize will contain the required size.\r
139 @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate.\r
140\r
141**/\r
142EFI_STATUS\r
143EFIAPI\r
144ConvertBmpToGopBlt (\r
145 IN VOID *BmpImage,\r
146 IN UINTN BmpImageSize,\r
147 IN OUT VOID **GopBlt,\r
148 IN OUT UINTN *GopBltSize,\r
149 OUT UINTN *PixelHeight,\r
150 OUT UINTN *PixelWidth\r
151 )\r
152{\r
153 UINT8 *Image;\r
154 UINT8 *ImageHeader;\r
155 BMP_IMAGE_HEADER *BmpHeader;\r
156 BMP_COLOR_MAP *BmpColorMap;\r
157 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
158 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
159 UINTN BltBufferSize;\r
160 UINTN Index;\r
161 UINTN Height;\r
162 UINTN Width;\r
163 UINTN ImageIndex;\r
164 BOOLEAN IsAllocated;\r
165\r
166 BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;\r
167\r
168 if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {\r
169 return EFI_UNSUPPORTED;\r
170 }\r
171\r
172 //\r
173 // Doesn't support compress.\r
174 //\r
175 if (BmpHeader->CompressionType != 0) {\r
176 return EFI_UNSUPPORTED;\r
177 }\r
178\r
179 //\r
180 // Calculate Color Map offset in the image.\r
181 //\r
182 Image = BmpImage;\r
183 BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));\r
184\r
185 //\r
186 // Calculate graphics image data address in the image\r
187 //\r
188 Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;\r
189 ImageHeader = Image;\r
190\r
191 //\r
192 // Calculate the BltBuffer needed size.\r
193 //\r
194 BltBufferSize = BmpHeader->PixelWidth * BmpHeader->PixelHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
195 IsAllocated = FALSE;\r
196 if (*GopBlt == NULL) {\r
197 //\r
198 // GopBlt is not allocated by caller.\r
199 //\r
200 *GopBltSize = BltBufferSize;\r
201 *GopBlt = AllocatePool (*GopBltSize);\r
202 IsAllocated = TRUE;\r
203 if (*GopBlt == NULL) {\r
204 return EFI_OUT_OF_RESOURCES;\r
205 }\r
206 } else {\r
207 //\r
208 // GopBlt has been allocated by caller.\r
209 //\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 1-bit (2 colors) 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
242\r
243 case 4:\r
244 //\r
245 // Convert 4-bit (16 colors) 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 8-bit (256 colors) 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 //\r
272 // It is 24-bit BMP.\r
273 //\r
274 Blt->Blue = *Image++;\r
275 Blt->Green = *Image++;\r
276 Blt->Red = *Image;\r
277 break;\r
278\r
279 default:\r
280 //\r
281 // Other bit format BMP is not supported.\r
282 //\r
283 if (IsAllocated) {\r
284 FreePool (*GopBlt);\r
285 *GopBlt = NULL;\r
286 }\r
287 return EFI_UNSUPPORTED;\r
288 break;\r
289 };\r
290\r
291 }\r
292\r
293 ImageIndex = (UINTN) (Image - ImageHeader);\r
294 if ((ImageIndex % 4) != 0) {\r
295 //\r
296 // Bmp Image starts each row on a 32-bit boundary!\r
297 //\r
298 Image = Image + (4 - (ImageIndex % 4));\r
299 }\r
300 }\r
301\r
302 return EFI_SUCCESS;\r
303}\r
304\r
305\r
306/**\r
307 Use Console Control Protocol to lock the Console In Spliter virtual handle. \r
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
312 @param Password Password used to lock ConIn device.\r
313\r
314 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.\r
315 @retval EFI_UNSUPPORTED Password not found.\r
316\r
317**/\r
318EFI_STATUS\r
319EFIAPI\r
320LockKeyboards (\r
321 IN CHAR16 *Password\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
337/**\r
338 Use Console Control to turn off UGA based Simple Text Out consoles from going\r
339 to the UGA device. Put up LogoFile on every UGA device that is a console.\r
340\r
341 @param LogoFile File name of logo to display on the center of the screen.\r
342\r
343 @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed.\r
344 @retval EFI_UNSUPPORTED Logo not found.\r
345\r
346**/\r
347EFI_STATUS\r
348EFIAPI\r
349EnableQuietBoot (\r
350 IN EFI_GUID *LogoFile\r
351 )\r
352{\r
353 return EnableQuietBootEx (LogoFile, NULL);\r
354}\r
355\r
356/**\r
357 Use Console Control to turn off UGA based Simple Text Out consoles from going\r
358 to the UGA device. Put up LogoFile on every UGA device that is a console\r
359\r
360 @param LogoFile File name of logo to display on the center of the screen.\r
361 @param ImageHandle The driver image handle of the caller. The parameter is used to\r
362 optimize the loading of the logo file so that the FV from which\r
363 the driver image is loaded will be tried first.\r
364\r
365 @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed.\r
366 @retval EFI_UNSUPPORTED Logo not found.\r
367\r
368**/\r
369EFI_STATUS\r
370EFIAPI\r
371EnableQuietBootEx (\r
372 IN EFI_GUID *LogoFile,\r
373 IN EFI_HANDLE ImageHandle\r
374 )\r
375{\r
376 EFI_STATUS Status;\r
377 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
378 EFI_OEM_BADGING_PROTOCOL *Badging;\r
379 UINT32 SizeOfX;\r
380 UINT32 SizeOfY;\r
381 INTN DestX;\r
382 INTN DestY;\r
383 UINT8 *ImageData;\r
384 UINTN ImageSize;\r
385 UINTN BltSize;\r
386 UINT32 Instance;\r
387 EFI_BADGING_FORMAT Format;\r
388 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;\r
389 UINTN CoordinateX;\r
390 UINTN CoordinateY;\r
391 UINTN Height;\r
392 UINTN Width;\r
393 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
394 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
395 UINT32 ColorDepth;\r
396 UINT32 RefreshRate;\r
397 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
398\r
399 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
400 if (EFI_ERROR (Status)) {\r
401 return EFI_UNSUPPORTED;\r
402 }\r
403\r
404 UgaDraw = NULL;\r
405 //\r
406 // Try to open GOP first\r
407 //\r
408 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);\r
409 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
410 GraphicsOutput = NULL;\r
411 //\r
412 // Open GOP failed, try to open UGA\r
413 //\r
414 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);\r
415 }\r
416 if (EFI_ERROR (Status)) {\r
417 return EFI_UNSUPPORTED;\r
418 }\r
419\r
420 Badging = NULL;\r
421 Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);\r
422\r
423 //\r
424 // Set console control to graphics mode.\r
425 //\r
426 Status = ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics);\r
427 if (EFI_ERROR (Status)) {\r
428 return EFI_UNSUPPORTED;\r
429 }\r
430\r
431 if (GraphicsOutput != NULL) {\r
432 SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
433 SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
434 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
435 Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);\r
436 if (EFI_ERROR (Status)) {\r
437 return EFI_UNSUPPORTED;\r
438 }\r
439 } else {\r
440 return EFI_UNSUPPORTED;\r
441 }\r
442\r
443 Instance = 0;\r
444 while (1) {\r
445 ImageData = NULL;\r
446 ImageSize = 0;\r
447\r
448 if (Badging != NULL) {\r
449 //\r
450 // Get image from OEMBadging protocol.\r
451 //\r
452 Status = Badging->GetImage (\r
453 Badging,\r
454 &Instance,\r
455 &Format,\r
456 &ImageData,\r
457 &ImageSize,\r
458 &Attribute,\r
459 &CoordinateX,\r
460 &CoordinateY\r
461 );\r
462 if (EFI_ERROR (Status)) {\r
463 return Status;\r
464 }\r
465\r
466 //\r
467 // Currently only support BMP format.\r
468 //\r
469 if (Format != EfiBadgingFormatBMP) {\r
676df92c 470 if (ImageData != NULL) {\r
471 FreePool (ImageData);\r
472 }\r
677472aa 473 continue;\r
474 }\r
475 } else {\r
476 //\r
477 // Get the specified image from FV.\r
478 //\r
479 Status = GetGraphicsBitMapFromFVEx (ImageHandle, LogoFile, (VOID **) &ImageData, &ImageSize);\r
480 if (EFI_ERROR (Status)) {\r
481 return EFI_UNSUPPORTED;\r
482 }\r
483\r
484 CoordinateX = 0;\r
485 CoordinateY = 0;\r
486 Attribute = EfiBadgingDisplayAttributeCenter;\r
487 }\r
488\r
489 Blt = NULL;\r
490 Status = ConvertBmpToGopBlt (\r
491 ImageData,\r
492 ImageSize,\r
493 (VOID **) &Blt,\r
494 &BltSize,\r
495 &Height,\r
496 &Width\r
497 );\r
498 if (EFI_ERROR (Status)) {\r
676df92c 499 if (ImageData != NULL) {\r
500 FreePool (ImageData);\r
501 }\r
677472aa 502 if (Badging == NULL) {\r
503 return Status;\r
504 } else {\r
505 continue;\r
506 }\r
507 }\r
508\r
509 //\r
510 // Caculate the display position according to Attribute.\r
511 //\r
512 switch (Attribute) {\r
513 case EfiBadgingDisplayAttributeLeftTop:\r
514 DestX = CoordinateX;\r
515 DestY = CoordinateY;\r
516 break;\r
517\r
518 case EfiBadgingDisplayAttributeCenterTop:\r
519 DestX = (SizeOfX - Width) / 2;\r
520 DestY = CoordinateY;\r
521 break;\r
522\r
523 case EfiBadgingDisplayAttributeRightTop:\r
524 DestX = (SizeOfX - Width - CoordinateX);\r
525 DestY = CoordinateY;;\r
526 break;\r
527\r
528 case EfiBadgingDisplayAttributeCenterRight:\r
529 DestX = (SizeOfX - Width - CoordinateX);\r
530 DestY = (SizeOfY - Height) / 2;\r
531 break;\r
532\r
533 case EfiBadgingDisplayAttributeRightBottom:\r
534 DestX = (SizeOfX - Width - CoordinateX);\r
535 DestY = (SizeOfY - Height - CoordinateY);\r
536 break;\r
537\r
538 case EfiBadgingDisplayAttributeCenterBottom:\r
539 DestX = (SizeOfX - Width) / 2;\r
540 DestY = (SizeOfY - Height - CoordinateY);\r
541 break;\r
542\r
543 case EfiBadgingDisplayAttributeLeftBottom:\r
544 DestX = CoordinateX;\r
545 DestY = (SizeOfY - Height - CoordinateY);\r
546 break;\r
547\r
548 case EfiBadgingDisplayAttributeCenterLeft:\r
549 DestX = CoordinateX;\r
550 DestY = (SizeOfY - Height) / 2;\r
551 break;\r
552\r
553 case EfiBadgingDisplayAttributeCenter:\r
554 DestX = (SizeOfX - Width) / 2;\r
555 DestY = (SizeOfY - Height) / 2;\r
556 break;\r
557\r
558 default:\r
559 DestX = CoordinateX;\r
560 DestY = CoordinateY;\r
561 break;\r
562 }\r
563\r
564 if ((DestX >= 0) && (DestY >= 0)) {\r
565 if (GraphicsOutput != NULL) {\r
566 Status = GraphicsOutput->Blt (\r
567 GraphicsOutput,\r
568 Blt,\r
569 EfiBltBufferToVideo,\r
570 0,\r
571 0,\r
572 (UINTN) DestX,\r
573 (UINTN) DestY,\r
574 Width,\r
575 Height,\r
576 Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
577 );\r
578 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
579 Status = UgaDraw->Blt (\r
580 UgaDraw,\r
581 (EFI_UGA_PIXEL *) Blt,\r
582 EfiUgaBltBufferToVideo,\r
583 0,\r
584 0,\r
585 (UINTN) DestX,\r
586 (UINTN) DestY,\r
587 Width,\r
588 Height,\r
589 Width * sizeof (EFI_UGA_PIXEL)\r
590 );\r
591 } else {\r
592 Status = EFI_UNSUPPORTED;\r
593 }\r
594 }\r
595\r
676df92c 596 if (ImageData != NULL) {\r
597 FreePool (ImageData);\r
598 }\r
599 if (Blt != NULL) {\r
600 FreePool (Blt);\r
601 }\r
677472aa 602\r
603 if (Badging == NULL) {\r
604 break;\r
605 }\r
606 }\r
607\r
608 return Status;\r
609}\r
610\r
611/**\r
612 Use Console Control to turn on UGA based Simple Text Out consoles. The UGA \r
613 Simple Text Out screens will now be synced up with all non UGA output devices\r
614\r
615 @retval EFI_SUCCESS UGA devices are back in text mode and synced up.\r
616 @retval EFI_UNSUPPORTED Logo not found\r
617\r
618**/\r
619EFI_STATUS\r
620EFIAPI\r
621DisableQuietBoot (\r
622 VOID\r
623 )\r
624{\r
625 EFI_STATUS Status;\r
626 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
627\r
628 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
629 if (EFI_ERROR (Status)) {\r
630 return EFI_UNSUPPORTED;\r
631 }\r
632\r
633 //\r
634 // Set console control to text mode.\r
635 //\r
636 return ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);\r
637}\r
638\r
639/**\r
640 Internal display string worker function.\r
641\r
642 @param GraphicsOutput Graphics output protocol interface.\r
643 @param UgaDraw UGA draw protocol interface.\r
644 @param Sto Simple text out protocol interface.\r
645 @param X X coordinate to start printing.\r
646 @param Y Y coordinate to start printing.\r
647 @param Foreground Foreground color.\r
648 @param Background Background color.\r
649 @param fmt Format string.\r
650 @param args Print arguments.\r
651\r
652 @return Number of Characters printed. Zero means no any character \r
653 displayed successfully.\r
654\r
655**/\r
656UINTN\r
a7e883d8 657Print (\r
677472aa 658 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
659 IN EFI_UGA_DRAW_PROTOCOL *UgaDraw,\r
660 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Sto,\r
661 IN UINTN X,\r
662 IN UINTN Y,\r
663 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,\r
664 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background,\r
665 IN CHAR16 *fmt,\r
666 IN VA_LIST args\r
667 )\r
668{\r
669 VOID *Buffer;\r
670 EFI_STATUS Status;\r
671 UINTN Index;\r
672 CHAR16 *UnicodeWeight;\r
673 UINT32 HorizontalResolution;\r
674 UINT32 VerticalResolution;\r
675 UINT32 ColorDepth;\r
676 UINT32 RefreshRate;\r
677 UINTN BufferLen;\r
678 UINTN LineBufferLen;\r
679 EFI_HII_FONT_PROTOCOL *HiiFont;\r
680 EFI_IMAGE_OUTPUT *Blt;\r
681 EFI_FONT_DISPLAY_INFO *FontInfo;\r
682 EFI_HII_ROW_INFO *RowInfoArray;\r
683 UINTN RowInfoArraySize;\r
684 UINTN PrintNum; \r
685\r
686 //\r
687 // For now, allocate an arbitrarily long buffer\r
688 //\r
689 Buffer = AllocateZeroPool (0x10000);\r
690 if (Buffer == NULL) {\r
691 return 0;\r
692 }\r
693\r
694 HorizontalResolution = 0;\r
695 VerticalResolution = 0;\r
696 Blt = NULL;\r
697 FontInfo = NULL;\r
698 PrintNum = 0;\r
699\r
700 if (GraphicsOutput != NULL) {\r
701 HorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;\r
702 VerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;\r
703 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
704 UgaDraw->GetMode (UgaDraw, &HorizontalResolution, &VerticalResolution, &ColorDepth, &RefreshRate);\r
705 } else {\r
706 Status = EFI_UNSUPPORTED;\r
707 goto Error;\r
708 }\r
709\r
710 ASSERT ((HorizontalResolution != 0) && (VerticalResolution !=0));\r
711\r
712 Status = gBS->LocateProtocol (&gEfiHiiFontProtocolGuid, NULL, (VOID **) &HiiFont);\r
713 if (EFI_ERROR (Status)) {\r
714 goto Error;\r
715 }\r
716\r
717 PrintNum = UnicodeVSPrint (Buffer, 0x10000, fmt, args);\r
718\r
719 UnicodeWeight = (CHAR16 *) Buffer;\r
720\r
721 for (Index = 0; UnicodeWeight[Index] != 0; Index++) {\r
722 if (UnicodeWeight[Index] == CHAR_BACKSPACE ||\r
723 UnicodeWeight[Index] == CHAR_LINEFEED ||\r
724 UnicodeWeight[Index] == CHAR_CARRIAGE_RETURN) {\r
725 UnicodeWeight[Index] = 0;\r
726 }\r
727 }\r
728\r
729 BufferLen = StrLen (Buffer);\r
730\r
731 LineBufferLen = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * HorizontalResolution * EFI_GLYPH_HEIGHT;\r
732 if (EFI_GLYPH_WIDTH * EFI_GLYPH_HEIGHT * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * BufferLen > LineBufferLen) {\r
733 Status = EFI_INVALID_PARAMETER;\r
734 goto Error;\r
735 }\r
736\r
737 Blt = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
738 if (Blt == NULL) {\r
739 Status = EFI_OUT_OF_RESOURCES;\r
740 goto Error;\r
741 }\r
742\r
743 Blt->Width = (UINT16) (HorizontalResolution);\r
744 Blt->Height = (UINT16) (VerticalResolution);\r
745\r
746 FontInfo = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO));\r
747 if (FontInfo == NULL) {\r
748 Status = EFI_OUT_OF_RESOURCES;\r
749 goto Error;\r
750 }\r
751 if (Foreground != NULL) {\r
752 CopyMem (&FontInfo->ForegroundColor, Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
753 } else {\r
754 CopyMem (\r
755 &FontInfo->ForegroundColor,\r
756 &mEfiColors[Sto->Mode->Attribute & 0x0f],\r
757 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
758 );\r
759 }\r
760 if (Background != NULL) {\r
761 CopyMem (&FontInfo->BackgroundColor, Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
762 } else {\r
763 CopyMem (\r
764 &FontInfo->BackgroundColor,\r
765 &mEfiColors[Sto->Mode->Attribute >> 4],\r
766 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
767 );\r
768 }\r
769\r
770 if (GraphicsOutput != NULL) {\r
771 Blt->Image.Screen = GraphicsOutput;\r
772 \r
773 Status = HiiFont->StringToImage (\r
774 HiiFont,\r
775 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_DIRECT_TO_SCREEN,\r
776 Buffer,\r
777 FontInfo,\r
778 &Blt,\r
779 X,\r
780 Y,\r
781 NULL,\r
782 NULL,\r
783 NULL\r
784 );\r
785\r
786 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
787 ASSERT (UgaDraw!= NULL);\r
788\r
789 Blt->Image.Bitmap = AllocateZeroPool (Blt->Width * Blt->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
790 if (Blt->Image.Bitmap == NULL) {\r
676df92c 791 FreePool (Blt);\r
792 FreePool (Buffer);\r
677472aa 793 return EFI_OUT_OF_RESOURCES;\r
794 }\r
795\r
796 RowInfoArray = NULL;\r
797 //\r
798 // StringToImage only support blt'ing image to device using GOP protocol. If GOP is not supported in this platform,\r
799 // we ask StringToImage to print the string to blt buffer, then blt to device using UgaDraw.\r
800 //\r
801 Status = HiiFont->StringToImage (\r
802 HiiFont,\r
803 EFI_HII_IGNORE_IF_NO_GLYPH,\r
804 Buffer,\r
805 FontInfo,\r
806 &Blt,\r
807 X,\r
808 Y,\r
809 &RowInfoArray,\r
810 &RowInfoArraySize,\r
811 NULL\r
812 );\r
813\r
814 if (!EFI_ERROR (Status)) {\r
815 //\r
816 // Line breaks are handled by caller of DrawUnicodeWeightAtCursorN, so the updated parameter RowInfoArraySize by StringToImage will\r
817 // always be 1 or 0 (if there is no valid Unicode Char can be printed). ASSERT here to make sure.\r
818 //\r
819 ASSERT (RowInfoArraySize <= 1);\r
820\r
821 Status = UgaDraw->Blt (\r
822 UgaDraw,\r
823 (EFI_UGA_PIXEL *) Blt->Image.Bitmap,\r
824 EfiUgaBltBufferToVideo,\r
825 X,\r
826 Y,\r
827 X,\r
828 Y,\r
829 RowInfoArray[0].LineWidth,\r
830 RowInfoArray[0].LineHeight,\r
831 Blt->Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
832 );\r
833 }\r
834\r
676df92c 835 if (RowInfoArray != NULL) {\r
836 FreePool (RowInfoArray);\r
837 }\r
838 if (Blt->Image.Bitmap != NULL) {\r
839 FreePool (Blt->Image.Bitmap);\r
840 }\r
677472aa 841 } else {\r
842 Status = EFI_UNSUPPORTED;\r
843 }\r
844\r
845Error:\r
676df92c 846 if (Blt != NULL) {\r
847 FreePool (Blt);\r
848 }\r
849 if (FontInfo != NULL) { \r
850 FreePool (FontInfo);\r
851 }\r
677472aa 852 FreePool (Buffer);\r
853\r
854 if (EFI_ERROR (Status)) {\r
855 return PrintNum;\r
856 } else {\r
857 return 0;\r
858 }\r
859}\r
860\r
861/**\r
862 Print Unicode string to graphics screen at the given X,Y coordinates of the graphics screen.\r
863 see definition of Print to find rules for constructing Fmt.\r
864\r
865 @param X Row to start printing at.\r
866 @param Y Column to start printing at.\r
867 @param ForeGround Foreground color.\r
868 @param BackGround background color.\r
869 @param Fmt Print format sting. See definition of Print.\r
870 @param ... Argumnet stream defined by Fmt string.\r
871\r
872 @return Number of Characters printed. Zero means no any character \r
873 displayed successfully.\r
874\r
875**/\r
876UINTN\r
877EFIAPI\r
878PrintXY (\r
879 IN UINTN X,\r
880 IN UINTN Y,\r
881 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ForeGround, OPTIONAL\r
882 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BackGround, OPTIONAL\r
883 IN CHAR16 *Fmt,\r
884 ...\r
885 )\r
886{\r
887 EFI_HANDLE Handle;\r
888 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
889 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
890 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Sto;\r
891 EFI_STATUS Status;\r
892 VA_LIST Args;\r
893\r
894 VA_START (Args, Fmt);\r
895\r
896 Handle = gST->ConsoleOutHandle;\r
897\r
898 Status = gBS->HandleProtocol (\r
899 Handle,\r
900 &gEfiGraphicsOutputProtocolGuid,\r
901 (VOID **) &GraphicsOutput\r
902 );\r
903\r
904 UgaDraw = NULL;\r
905 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
906 //\r
907 // If no GOP available, try to open UGA Draw protocol if supported.\r
908 //\r
909 GraphicsOutput = NULL;\r
910\r
911 Status = gBS->HandleProtocol (\r
912 Handle,\r
913 &gEfiUgaDrawProtocolGuid,\r
914 (VOID **) &UgaDraw\r
915 );\r
916 }\r
917 if (EFI_ERROR (Status)) {\r
918 return 0;\r
919 }\r
920\r
921 Status = gBS->HandleProtocol (\r
922 Handle,\r
923 &gEfiSimpleTextOutProtocolGuid,\r
924 (VOID **) &Sto\r
925 );\r
926\r
927 if (EFI_ERROR (Status)) {\r
928 return 0;\r
929 }\r
930\r
a7e883d8 931 return Print (GraphicsOutput, UgaDraw, Sto, X, Y, ForeGround, BackGround, Fmt, Args);\r
677472aa 932}\r
933\r