]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Library/GraphicsLib/Graphics.c
Patch to remove STATIC modifier. This is on longer recommended by EFI Framework codin...
[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
ed7752ec 144EFI_STATUS\r
145ConvertBmpToGopBlt (\r
146 IN VOID *BmpImage,\r
147 IN UINTN BmpImageSize,\r
148 IN OUT VOID **GopBlt,\r
149 IN OUT UINTN *GopBltSize,\r
150 OUT UINTN *PixelHeight,\r
151 OUT UINTN *PixelWidth\r
152 )\r
45e6322c 153\r
45e6322c 154{\r
155 UINT8 *Image;\r
156 UINT8 *ImageHeader;\r
157 BMP_IMAGE_HEADER *BmpHeader;\r
158 BMP_COLOR_MAP *BmpColorMap;\r
159 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
160 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
161 UINTN BltBufferSize;\r
162 UINTN Index;\r
163 UINTN Height;\r
164 UINTN Width;\r
165 UINTN ImageIndex;\r
166 BOOLEAN IsAllocated;\r
67996c41 167\r
45e6322c 168 BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;\r
169 if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {\r
170 return EFI_UNSUPPORTED;\r
171 }\r
172\r
173 if (BmpHeader->CompressionType != 0) {\r
174 return EFI_UNSUPPORTED;\r
175 }\r
176\r
177 //\r
178 // Calculate Color Map offset in the image.\r
179 //\r
180 Image = BmpImage;\r
181 BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));\r
182\r
183 //\r
184 // Calculate graphics image data address in the image\r
185 //\r
186 Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;\r
187 ImageHeader = Image;\r
188\r
189 BltBufferSize = BmpHeader->PixelWidth * BmpHeader->PixelHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
190 IsAllocated = FALSE;\r
191 if (*GopBlt == NULL) {\r
192 *GopBltSize = BltBufferSize;\r
193 *GopBlt = AllocatePool (*GopBltSize);\r
194 IsAllocated = TRUE;\r
195 if (*GopBlt == NULL) {\r
196 return EFI_OUT_OF_RESOURCES;\r
197 }\r
198 } else {\r
199 if (*GopBltSize < BltBufferSize) {\r
200 *GopBltSize = BltBufferSize;\r
201 return EFI_BUFFER_TOO_SMALL;\r
202 }\r
203 }\r
204\r
205 *PixelWidth = BmpHeader->PixelWidth;\r
206 *PixelHeight = BmpHeader->PixelHeight;\r
207\r
208 //\r
209 // Convert image from BMP to Blt buffer format\r
210 //\r
211 BltBuffer = *GopBlt;\r
212 for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {\r
213 Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];\r
214 for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {\r
215 switch (BmpHeader->BitPerPixel) {\r
216 case 1:\r
217 //\r
218 // Convert 1bit BMP to 24-bit color\r
219 //\r
220 for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {\r
221 Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;\r
222 Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;\r
223 Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;\r
224 Blt++;\r
225 Width++;\r
226 }\r
227\r
228 Blt --;\r
229 Width --;\r
230 break;\r
67996c41 231\r
45e6322c 232 case 4:\r
233 //\r
234 // Convert BMP Palette to 24-bit color\r
235 //\r
236 Index = (*Image) >> 4;\r
237 Blt->Red = BmpColorMap[Index].Red;\r
238 Blt->Green = BmpColorMap[Index].Green;\r
239 Blt->Blue = BmpColorMap[Index].Blue;\r
240 if (Width < (BmpHeader->PixelWidth - 1)) {\r
241 Blt++;\r
242 Width++;\r
243 Index = (*Image) & 0x0f;\r
244 Blt->Red = BmpColorMap[Index].Red;\r
245 Blt->Green = BmpColorMap[Index].Green;\r
246 Blt->Blue = BmpColorMap[Index].Blue;\r
247 }\r
248 break;\r
249\r
250 case 8:\r
251 //\r
252 // Convert BMP Palette to 24-bit color\r
253 //\r
254 Blt->Red = BmpColorMap[*Image].Red;\r
255 Blt->Green = BmpColorMap[*Image].Green;\r
256 Blt->Blue = BmpColorMap[*Image].Blue;\r
257 break;\r
258\r
259 case 24:\r
260 Blt->Blue = *Image++;\r
261 Blt->Green = *Image++;\r
262 Blt->Red = *Image;\r
263 break;\r
264\r
265 default:\r
266 if (IsAllocated) {\r
267 gBS->FreePool (*GopBlt);\r
268 *GopBlt = NULL;\r
269 }\r
270 return EFI_UNSUPPORTED;\r
271 break;\r
272 };\r
273\r
274 }\r
275\r
276 ImageIndex = (UINTN) (Image - ImageHeader);\r
277 if ((ImageIndex % 4) != 0) {\r
278 //\r
279 // Bmp Image starts each row on a 32-bit boundary!\r
280 //\r
281 Image = Image + (4 - (ImageIndex % 4));\r
282 }\r
283 }\r
284\r
285 return EFI_SUCCESS;\r
286}\r
287\r
ed7752ec 288/**\r
67996c41 289 Use Console Control Protocol to lock the Console In Spliter virtual handle.\r
45e6322c 290 This is the ConInHandle and ConIn handle in the EFI system table. All key\r
291 presses will be ignored until the Password is typed in. The only way to\r
292 disable the password is to type it in to a ConIn device.\r
293\r
ed7752ec 294 @param Password - Password used to lock ConIn device\r
45e6322c 295\r
a477ccef 296 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully..\r
297 @retval EFI_UNSUPPORTED password not found\r
45e6322c 298\r
ed7752ec 299**/\r
300EFI_STATUS\r
301LockKeyboards (\r
302 IN CHAR16 *Password\r
303 )\r
45e6322c 304{\r
305 EFI_STATUS Status;\r
306 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
307\r
308 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
309 if (EFI_ERROR (Status)) {\r
310 return EFI_UNSUPPORTED;\r
311 }\r
312\r
313 Status = ConsoleControl->LockStdIn (ConsoleControl, Password);\r
314 return Status;\r
315}\r
316\r
ed7752ec 317/**\r
45e6322c 318 Use Console Control to turn off UGA based Simple Text Out consoles from going\r
319 to the UGA device. Put up LogoFile on every UGA device that is a console\r
320\r
ed7752ec 321 @param LogoFile - File name of logo to display on the center of the screen.\r
45e6322c 322\r
ed7752ec 323 @retval EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo\r
324 displayed.\r
325 @retval EFI_UNSUPPORTED - Logo not found\r
45e6322c 326\r
ed7752ec 327**/\r
328EFI_STATUS\r
329EnableQuietBoot (\r
330 IN EFI_GUID *LogoFile\r
331 )\r
45e6322c 332\r
45e6322c 333{\r
334 EFI_STATUS Status;\r
335 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
336 EFI_OEM_BADGING_PROTOCOL *Badging;\r
337 UINT32 SizeOfX;\r
338 UINT32 SizeOfY;\r
339 INTN DestX;\r
340 INTN DestY;\r
341 UINT8 *ImageData;\r
342 UINTN ImageSize;\r
343 UINTN BltSize;\r
344 UINT32 Instance;\r
345 EFI_BADGING_FORMAT Format;\r
346 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;\r
347 UINTN CoordinateX;\r
348 UINTN CoordinateY;\r
349 UINTN Height;\r
350 UINTN Width;\r
351 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
352 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
353 UINT32 ColorDepth;\r
354 UINT32 RefreshRate;\r
355 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
356\r
357 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
358 if (EFI_ERROR (Status)) {\r
359 return EFI_UNSUPPORTED;\r
360 }\r
361\r
362 UgaDraw = NULL;\r
363 //\r
364 // Try to open GOP first\r
365 //\r
67996c41 366 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);\r
8541adab 367 if (EFI_ERROR(Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
45e6322c 368 GraphicsOutput = NULL;\r
369 //\r
370 // Open GOP failed, try to open UGA\r
371 //\r
372 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);\r
8541adab 373 }\r
374 if (EFI_ERROR (Status)) {\r
375 return EFI_UNSUPPORTED;\r
45e6322c 376 }\r
377\r
378 Badging = NULL;\r
379 Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);\r
380\r
381 ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics);\r
382\r
383 if (GraphicsOutput != NULL) {\r
384 SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
385 SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
8541adab 386 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
45e6322c 387 Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);\r
388 if (EFI_ERROR (Status)) {\r
389 return EFI_UNSUPPORTED;\r
390 }\r
695f7e98 391 } else {\r
392 return EFI_UNSUPPORTED;\r
45e6322c 393 }\r
394\r
395 Instance = 0;\r
396 while (1) {\r
397 ImageData = NULL;\r
398 ImageSize = 0;\r
399\r
400 if (Badging != NULL) {\r
401 Status = Badging->GetImage (\r
402 Badging,\r
403 &Instance,\r
404 &Format,\r
405 &ImageData,\r
406 &ImageSize,\r
407 &Attribute,\r
408 &CoordinateX,\r
409 &CoordinateY\r
410 );\r
411 if (EFI_ERROR (Status)) {\r
412 return Status;\r
413 }\r
414\r
415 //\r
416 // Currently only support BMP format\r
417 //\r
418 if (Format != EfiBadgingFormatBMP) {\r
419 gBS->FreePool (ImageData);\r
420 continue;\r
421 }\r
422 } else {\r
423 Status = GetGraphicsBitMapFromFV (LogoFile, (VOID **) &ImageData, &ImageSize);\r
424 if (EFI_ERROR (Status)) {\r
425 return EFI_UNSUPPORTED;\r
426 }\r
427\r
428 CoordinateX = 0;\r
429 CoordinateY = 0;\r
430 Attribute = EfiBadgingDisplayAttributeCenter;\r
431 }\r
432\r
433 Blt = NULL;\r
434 BltSize = 0;\r
435 Status = ConvertBmpToGopBlt (\r
436 ImageData,\r
437 ImageSize,\r
438 (VOID**)&Blt,\r
439 &BltSize,\r
440 &Height,\r
441 &Width\r
442 );\r
443 if (EFI_ERROR (Status)) {\r
444 gBS->FreePool (ImageData);\r
445 if (Badging == NULL) {\r
446 return Status;\r
447 } else {\r
448 continue;\r
449 }\r
450 }\r
451\r
452 switch (Attribute) {\r
453 case EfiBadgingDisplayAttributeLeftTop:\r
454 DestX = CoordinateX;\r
455 DestY = CoordinateY;\r
456 break;\r
457\r
458 case EfiBadgingDisplayAttributeCenterTop:\r
459 DestX = (SizeOfX - Width) / 2;\r
460 DestY = CoordinateY;\r
461 break;\r
462\r
463 case EfiBadgingDisplayAttributeRightTop:\r
464 DestX = (SizeOfX - Width - CoordinateX);\r
465 DestY = CoordinateY;;\r
466 break;\r
467\r
468 case EfiBadgingDisplayAttributeCenterRight:\r
469 DestX = (SizeOfX - Width - CoordinateX);\r
470 DestY = (SizeOfY - Height) / 2;\r
471 break;\r
472\r
473 case EfiBadgingDisplayAttributeRightBottom:\r
474 DestX = (SizeOfX - Width - CoordinateX);\r
475 DestY = (SizeOfY - Height - CoordinateY);\r
476 break;\r
477\r
478 case EfiBadgingDisplayAttributeCenterBottom:\r
479 DestX = (SizeOfX - Width) / 2;\r
480 DestY = (SizeOfY - Height - CoordinateY);\r
481 break;\r
482\r
483 case EfiBadgingDisplayAttributeLeftBottom:\r
484 DestX = CoordinateX;\r
485 DestY = (SizeOfY - Height - CoordinateY);\r
486 break;\r
487\r
488 case EfiBadgingDisplayAttributeCenterLeft:\r
489 DestX = CoordinateX;\r
490 DestY = (SizeOfY - Height) / 2;\r
491 break;\r
492\r
493 case EfiBadgingDisplayAttributeCenter:\r
494 DestX = (SizeOfX - Width) / 2;\r
495 DestY = (SizeOfY - Height) / 2;\r
496 break;\r
497\r
498 default:\r
499 DestX = CoordinateX;\r
500 DestY = CoordinateY;\r
501 break;\r
502 }\r
503\r
504 if ((DestX >= 0) && (DestY >= 0)) {\r
505 if (GraphicsOutput != NULL) {\r
506 Status = GraphicsOutput->Blt (\r
507 GraphicsOutput,\r
508 Blt,\r
509 EfiBltBufferToVideo,\r
510 0,\r
511 0,\r
512 (UINTN) DestX,\r
513 (UINTN) DestY,\r
514 Width,\r
515 Height,\r
516 Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
517 );\r
8541adab 518 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
45e6322c 519 Status = UgaDraw->Blt (\r
520 UgaDraw,\r
521 (EFI_UGA_PIXEL *) Blt,\r
522 EfiUgaBltBufferToVideo,\r
523 0,\r
524 0,\r
525 (UINTN) DestX,\r
526 (UINTN) DestY,\r
527 Width,\r
528 Height,\r
529 Width * sizeof (EFI_UGA_PIXEL)\r
530 );\r
8541adab 531 } else {\r
532 Status = EFI_UNSUPPORTED;\r
45e6322c 533 }\r
534 }\r
535\r
536 gBS->FreePool (ImageData);\r
537 gBS->FreePool (Blt);\r
538\r
539 if (Badging == NULL) {\r
540 break;\r
541 }\r
542 }\r
543\r
544 return Status;\r
545}\r
546\r
ed7752ec 547/**\r
548 Use Console Control to turn on GOP/UGA based Simple Text Out consoles. The GOP/UGA\r
549 Simple Text Out screens will now be synced up with all non GOP/UGA output devices\r
45e6322c 550\r
ed7752ec 551 @retval EFI_SUCCESS - GOP/UGA devices are back in text mode and synced up.\r
552 @retval EFI_UNSUPPORTED - Logo not found\r
553**/\r
45e6322c 554EFI_STATUS\r
555DisableQuietBoot (\r
556 VOID\r
557 )\r
45e6322c 558\r
45e6322c 559{\r
560 EFI_STATUS Status;\r
561 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
562\r
563 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
564 if (EFI_ERROR (Status)) {\r
565 return EFI_UNSUPPORTED;\r
566 }\r
567\r
568 return ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);\r
569}\r
570\r
819d1488 571EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors[16] = {\r
45e6322c 572 { 0x00, 0x00, 0x00, 0x00 },\r
573 { 0x98, 0x00, 0x00, 0x00 },\r
574 { 0x00, 0x98, 0x00, 0x00 },\r
575 { 0x98, 0x98, 0x00, 0x00 },\r
576 { 0x00, 0x00, 0x98, 0x00 },\r
577 { 0x98, 0x00, 0x98, 0x00 },\r
578 { 0x00, 0x98, 0x98, 0x00 },\r
579 { 0x98, 0x98, 0x98, 0x00 },\r
580 { 0x10, 0x10, 0x10, 0x00 },\r
581 { 0xff, 0x10, 0x10, 0x00 },\r
582 { 0x10, 0xff, 0x10, 0x00 },\r
583 { 0xff, 0xff, 0x10, 0x00 },\r
584 { 0x10, 0x10, 0xff, 0x00 },\r
585 { 0xf0, 0x10, 0xff, 0x00 },\r
586 { 0x10, 0xff, 0xff, 0x00 },\r
587 { 0xff, 0xff, 0xff, 0x00 }\r
588};\r
589\r
ed7752ec 590/**\r
45e6322c 591 Display string worker for: Print, PrintAt, IPrint, IPrintAt\r
592\r
ed7752ec 593 @param GraphicsOutput - Graphics output protocol interface\r
45e6322c 594\r
ed7752ec 595 @param UgaDraw - UGA draw protocol interface\r
67996c41 596\r
ed7752ec 597 @param Sto - Simple text out protocol interface\r
67996c41 598\r
ed7752ec 599 @param X - X coordinate to start printing\r
67996c41 600\r
ed7752ec 601 @param Y - Y coordinate to start printing\r
67996c41 602\r
ed7752ec 603 @param Foreground - Foreground color\r
67996c41 604\r
ed7752ec 605 @param Background - Background color\r
67996c41 606\r
ed7752ec 607 @param fmt - Format string\r
67996c41 608\r
ed7752ec 609 @param args - Print arguments\r
67996c41 610\r
45e6322c 611\r
ed7752ec 612 @retval EFI_SUCCESS - success\r
613 @retval EFI_OUT_OF_RESOURCES - out of resources\r
45e6322c 614\r
ed7752ec 615**/\r
ed7752ec 616UINTN\r
617_IPrint (\r
618 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
619 IN EFI_UGA_DRAW_PROTOCOL *UgaDraw,\r
620 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Sto,\r
621 IN UINTN X,\r
622 IN UINTN Y,\r
623 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,\r
624 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background,\r
625 IN CHAR16 *fmt,\r
626 IN VA_LIST args\r
627 )\r
45e6322c 628\r
45e6322c 629{\r
62409219 630 VOID *Buffer;\r
631 EFI_STATUS Status;\r
632 UINT16 GlyphWidth;\r
633 UINT32 GlyphStatus;\r
634 UINT16 StringIndex;\r
635 UINTN Index;\r
636 CHAR16 *UnicodeWeight;\r
637 EFI_NARROW_GLYPH *Glyph;\r
638 EFI_HII_PROTOCOL *Hii;\r
639 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LineBuffer;\r
640 UINT32 HorizontalResolution;\r
641 UINT32 VerticalResolution;\r
642 UINT32 ColorDepth;\r
643 UINT32 RefreshRate;\r
644 UINTN BufferLen;\r
645 UINTN LineBufferLen;\r
646 UINTN BufferGlyphWidth;\r
45e6322c 647\r
648 GlyphStatus = 0;\r
b67754b9 649 HorizontalResolution = 0;\r
650 VerticalResolution = 0;\r
45e6322c 651\r
652 //\r
653 // For now, allocate an arbitrarily long buffer\r
654 //\r
655 Buffer = AllocateZeroPool (0x10000);\r
656 if (Buffer == NULL) {\r
657 return EFI_OUT_OF_RESOURCES;\r
658 }\r
67996c41 659\r
45e6322c 660 if (GraphicsOutput != NULL) {\r
661 HorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;\r
662 VerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;\r
8541adab 663 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
45e6322c 664 //\r
665 // Get the current mode information from the UGA Draw Protocol\r
666 //\r
667 UgaDraw->GetMode (UgaDraw, &HorizontalResolution, &VerticalResolution, &ColorDepth, &RefreshRate);\r
668 }\r
62409219 669 ASSERT ((HorizontalResolution != 0) && (VerticalResolution !=0));\r
45e6322c 670\r
62409219 671 LineBufferLen = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * HorizontalResolution * GLYPH_HEIGHT;\r
672 LineBuffer = AllocatePool (LineBufferLen);\r
45e6322c 673 if (LineBuffer == NULL) {\r
674 gBS->FreePool (Buffer);\r
675 return EFI_OUT_OF_RESOURCES;\r
676 }\r
677\r
678 Status = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, (VOID **) &Hii);\r
679 if (EFI_ERROR (Status)) {\r
680 goto Error;\r
681 }\r
682\r
683 UnicodeVSPrint (Buffer, 0x10000, fmt, args);\r
684\r
685 UnicodeWeight = (CHAR16 *) Buffer;\r
686\r
687 for (Index = 0; UnicodeWeight[Index] != 0; Index++) {\r
688 if (UnicodeWeight[Index] == CHAR_BACKSPACE ||\r
689 UnicodeWeight[Index] == CHAR_LINEFEED ||\r
690 UnicodeWeight[Index] == CHAR_CARRIAGE_RETURN) {\r
691 UnicodeWeight[Index] = 0;\r
692 }\r
693 }\r
694\r
62409219 695 BufferLen = StrLen (Buffer);\r
696\r
697 if (GLYPH_WIDTH * GLYPH_HEIGHT * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * BufferLen > LineBufferLen) {\r
698 Status = EFI_INVALID_PARAMETER;\r
699 goto Error;\r
700 }\r
701\r
702 for (Index = 0; Index < BufferLen; Index++) {\r
45e6322c 703 StringIndex = (UINT16) Index;\r
704 Status = Hii->GetGlyph (Hii, UnicodeWeight, &StringIndex, (UINT8 **) &Glyph, &GlyphWidth, &GlyphStatus);\r
705 if (EFI_ERROR (Status)) {\r
706 goto Error;\r
707 }\r
708\r
709 if (Foreground == NULL || Background == NULL) {\r
710 Status = Hii->GlyphToBlt (\r
711 Hii,\r
712 (UINT8 *) Glyph,\r
713 mEfiColors[Sto->Mode->Attribute & 0x0f],\r
714 mEfiColors[Sto->Mode->Attribute >> 4],\r
62409219 715 BufferLen,\r
45e6322c 716 GlyphWidth,\r
717 GLYPH_HEIGHT,\r
718 &LineBuffer[Index * GLYPH_WIDTH]\r
719 );\r
720 } else {\r
721 Status = Hii->GlyphToBlt (\r
722 Hii,\r
723 (UINT8 *) Glyph,\r
724 *Foreground,\r
725 *Background,\r
62409219 726 BufferLen,\r
45e6322c 727 GlyphWidth,\r
728 GLYPH_HEIGHT,\r
729 &LineBuffer[Index * GLYPH_WIDTH]\r
730 );\r
731 }\r
732 }\r
733\r
734 //\r
735 // Blt a character to the screen\r
736 //\r
62409219 737 BufferGlyphWidth = GLYPH_WIDTH * BufferLen;\r
45e6322c 738 if (GraphicsOutput != NULL) {\r
739 Status = GraphicsOutput->Blt (\r
740 GraphicsOutput,\r
741 LineBuffer,\r
742 EfiBltBufferToVideo,\r
743 0,\r
744 0,\r
745 X,\r
746 Y,\r
747 BufferGlyphWidth,\r
748 GLYPH_HEIGHT,\r
749 BufferGlyphWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
750 );\r
8541adab 751 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
45e6322c 752 Status = UgaDraw->Blt (\r
753 UgaDraw,\r
754 (EFI_UGA_PIXEL *) (UINTN) LineBuffer,\r
755 EfiUgaBltBufferToVideo,\r
756 0,\r
757 0,\r
758 X,\r
759 Y,\r
760 BufferGlyphWidth,\r
761 GLYPH_HEIGHT,\r
762 BufferGlyphWidth * sizeof (EFI_UGA_PIXEL)\r
763 );\r
8541adab 764 } else {\r
765 Status = EFI_UNSUPPORTED;\r
45e6322c 766 }\r
767\r
768Error:\r
769 gBS->FreePool (LineBuffer);\r
770 gBS->FreePool (Buffer);\r
771 return Status;\r
772}\r
773\r
ed7752ec 774/**\r
775 Prints a formatted unicode string to the default console\r
776\r
777 @param X - X coordinate to start printing\r
778\r
779 @param Y - Y coordinate to start printing\r
780\r
781 @param ForeGround - Foreground color\r
782\r
783 @param BackGround - Background color\r
784\r
785 @param Fmt - Format string\r
786\r
787 @param ... - Print arguments\r
45e6322c 788\r
ed7752ec 789\r
790 @retval Length of string printed to the console\r
791\r
792**/\r
45e6322c 793UINTN\r
794PrintXY (\r
795 IN UINTN X,\r
796 IN UINTN Y,\r
797 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ForeGround, OPTIONAL\r
798 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BackGround, OPTIONAL\r
799 IN CHAR16 *Fmt,\r
800 ...\r
801 )\r
45e6322c 802{\r
803 EFI_HANDLE Handle;\r
804\r
805 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
806 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
807 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Sto;\r
808 EFI_STATUS Status;\r
809 VA_LIST Args;\r
810\r
811 VA_START (Args, Fmt);\r
812\r
813 UgaDraw = NULL;\r
814\r
815 Handle = gST->ConsoleOutHandle;\r
816\r
817 Status = gBS->HandleProtocol (\r
818 Handle,\r
819 &gEfiGraphicsOutputProtocolGuid,\r
820 (VOID **) &GraphicsOutput\r
821 );\r
822\r
8541adab 823 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
45e6322c 824 GraphicsOutput = NULL;\r
825\r
826 Status = gBS->HandleProtocol (\r
827 Handle,\r
828 &gEfiUgaDrawProtocolGuid,\r
829 (VOID **) &UgaDraw\r
830 );\r
8541adab 831 }\r
45e6322c 832\r
8541adab 833 if (EFI_ERROR (Status)) {\r
834 return Status;\r
45e6322c 835 }\r
836\r
837 Status = gBS->HandleProtocol (\r
838 Handle,\r
839 &gEfiSimpleTextOutProtocolGuid,\r
840 (VOID **) &Sto\r
841 );\r
842\r
843 if (EFI_ERROR (Status)) {\r
844 return Status;\r
845 }\r
846\r
847 return _IPrint (GraphicsOutput, UgaDraw, Sto, X, Y, ForeGround, BackGround, Fmt, Args);\r
848}\r
ed7752ec 849\r