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