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