]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Library/GraphicsLib/Graphics.c
cleanup the improper comments for function return value in LockKeyboards()
[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
a477ccef 297 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully..\r
298 @retval EFI_UNSUPPORTED password not found\r
45e6322c 299\r
ed7752ec 300**/\r
301EFI_STATUS\r
302LockKeyboards (\r
303 IN CHAR16 *Password\r
304 )\r
45e6322c 305{\r
306 EFI_STATUS Status;\r
307 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
308\r
309 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
310 if (EFI_ERROR (Status)) {\r
311 return EFI_UNSUPPORTED;\r
312 }\r
313\r
314 Status = ConsoleControl->LockStdIn (ConsoleControl, Password);\r
315 return Status;\r
316}\r
317\r
ed7752ec 318/**\r
45e6322c 319 Use Console Control to turn off UGA based Simple Text Out consoles from going\r
320 to the UGA device. Put up LogoFile on every UGA device that is a console\r
321\r
ed7752ec 322 @param LogoFile - File name of logo to display on the center of the screen.\r
45e6322c 323\r
ed7752ec 324 @retval EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo\r
325 displayed.\r
326 @retval EFI_UNSUPPORTED - Logo not found\r
45e6322c 327\r
ed7752ec 328**/\r
329EFI_STATUS\r
330EnableQuietBoot (\r
331 IN EFI_GUID *LogoFile\r
332 )\r
45e6322c 333\r
45e6322c 334{\r
335 EFI_STATUS Status;\r
336 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
337 EFI_OEM_BADGING_PROTOCOL *Badging;\r
338 UINT32 SizeOfX;\r
339 UINT32 SizeOfY;\r
340 INTN DestX;\r
341 INTN DestY;\r
342 UINT8 *ImageData;\r
343 UINTN ImageSize;\r
344 UINTN BltSize;\r
345 UINT32 Instance;\r
346 EFI_BADGING_FORMAT Format;\r
347 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;\r
348 UINTN CoordinateX;\r
349 UINTN CoordinateY;\r
350 UINTN Height;\r
351 UINTN Width;\r
352 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
353 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
354 UINT32 ColorDepth;\r
355 UINT32 RefreshRate;\r
356 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
357\r
358 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
359 if (EFI_ERROR (Status)) {\r
360 return EFI_UNSUPPORTED;\r
361 }\r
362\r
363 UgaDraw = NULL;\r
364 //\r
365 // Try to open GOP first\r
366 //\r
67996c41 367 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);\r
8541adab 368 if (EFI_ERROR(Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
45e6322c 369 GraphicsOutput = NULL;\r
370 //\r
371 // Open GOP failed, try to open UGA\r
372 //\r
373 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);\r
8541adab 374 }\r
375 if (EFI_ERROR (Status)) {\r
376 return EFI_UNSUPPORTED;\r
45e6322c 377 }\r
378\r
379 Badging = NULL;\r
380 Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);\r
381\r
382 ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics);\r
383\r
384 if (GraphicsOutput != NULL) {\r
385 SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
386 SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
8541adab 387 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
45e6322c 388 Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);\r
389 if (EFI_ERROR (Status)) {\r
390 return EFI_UNSUPPORTED;\r
391 }\r
695f7e98 392 } else {\r
393 return EFI_UNSUPPORTED;\r
45e6322c 394 }\r
395\r
396 Instance = 0;\r
397 while (1) {\r
398 ImageData = NULL;\r
399 ImageSize = 0;\r
400\r
401 if (Badging != NULL) {\r
402 Status = Badging->GetImage (\r
403 Badging,\r
404 &Instance,\r
405 &Format,\r
406 &ImageData,\r
407 &ImageSize,\r
408 &Attribute,\r
409 &CoordinateX,\r
410 &CoordinateY\r
411 );\r
412 if (EFI_ERROR (Status)) {\r
413 return Status;\r
414 }\r
415\r
416 //\r
417 // Currently only support BMP format\r
418 //\r
419 if (Format != EfiBadgingFormatBMP) {\r
420 gBS->FreePool (ImageData);\r
421 continue;\r
422 }\r
423 } else {\r
424 Status = GetGraphicsBitMapFromFV (LogoFile, (VOID **) &ImageData, &ImageSize);\r
425 if (EFI_ERROR (Status)) {\r
426 return EFI_UNSUPPORTED;\r
427 }\r
428\r
429 CoordinateX = 0;\r
430 CoordinateY = 0;\r
431 Attribute = EfiBadgingDisplayAttributeCenter;\r
432 }\r
433\r
434 Blt = NULL;\r
435 BltSize = 0;\r
436 Status = ConvertBmpToGopBlt (\r
437 ImageData,\r
438 ImageSize,\r
439 (VOID**)&Blt,\r
440 &BltSize,\r
441 &Height,\r
442 &Width\r
443 );\r
444 if (EFI_ERROR (Status)) {\r
445 gBS->FreePool (ImageData);\r
446 if (Badging == NULL) {\r
447 return Status;\r
448 } else {\r
449 continue;\r
450 }\r
451 }\r
452\r
453 switch (Attribute) {\r
454 case EfiBadgingDisplayAttributeLeftTop:\r
455 DestX = CoordinateX;\r
456 DestY = CoordinateY;\r
457 break;\r
458\r
459 case EfiBadgingDisplayAttributeCenterTop:\r
460 DestX = (SizeOfX - Width) / 2;\r
461 DestY = CoordinateY;\r
462 break;\r
463\r
464 case EfiBadgingDisplayAttributeRightTop:\r
465 DestX = (SizeOfX - Width - CoordinateX);\r
466 DestY = CoordinateY;;\r
467 break;\r
468\r
469 case EfiBadgingDisplayAttributeCenterRight:\r
470 DestX = (SizeOfX - Width - CoordinateX);\r
471 DestY = (SizeOfY - Height) / 2;\r
472 break;\r
473\r
474 case EfiBadgingDisplayAttributeRightBottom:\r
475 DestX = (SizeOfX - Width - CoordinateX);\r
476 DestY = (SizeOfY - Height - CoordinateY);\r
477 break;\r
478\r
479 case EfiBadgingDisplayAttributeCenterBottom:\r
480 DestX = (SizeOfX - Width) / 2;\r
481 DestY = (SizeOfY - Height - CoordinateY);\r
482 break;\r
483\r
484 case EfiBadgingDisplayAttributeLeftBottom:\r
485 DestX = CoordinateX;\r
486 DestY = (SizeOfY - Height - CoordinateY);\r
487 break;\r
488\r
489 case EfiBadgingDisplayAttributeCenterLeft:\r
490 DestX = CoordinateX;\r
491 DestY = (SizeOfY - Height) / 2;\r
492 break;\r
493\r
494 case EfiBadgingDisplayAttributeCenter:\r
495 DestX = (SizeOfX - Width) / 2;\r
496 DestY = (SizeOfY - Height) / 2;\r
497 break;\r
498\r
499 default:\r
500 DestX = CoordinateX;\r
501 DestY = CoordinateY;\r
502 break;\r
503 }\r
504\r
505 if ((DestX >= 0) && (DestY >= 0)) {\r
506 if (GraphicsOutput != NULL) {\r
507 Status = GraphicsOutput->Blt (\r
508 GraphicsOutput,\r
509 Blt,\r
510 EfiBltBufferToVideo,\r
511 0,\r
512 0,\r
513 (UINTN) DestX,\r
514 (UINTN) DestY,\r
515 Width,\r
516 Height,\r
517 Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
518 );\r
8541adab 519 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
45e6322c 520 Status = UgaDraw->Blt (\r
521 UgaDraw,\r
522 (EFI_UGA_PIXEL *) Blt,\r
523 EfiUgaBltBufferToVideo,\r
524 0,\r
525 0,\r
526 (UINTN) DestX,\r
527 (UINTN) DestY,\r
528 Width,\r
529 Height,\r
530 Width * sizeof (EFI_UGA_PIXEL)\r
531 );\r
8541adab 532 } else {\r
533 Status = EFI_UNSUPPORTED;\r
45e6322c 534 }\r
535 }\r
536\r
537 gBS->FreePool (ImageData);\r
538 gBS->FreePool (Blt);\r
539\r
540 if (Badging == NULL) {\r
541 break;\r
542 }\r
543 }\r
544\r
545 return Status;\r
546}\r
547\r
ed7752ec 548/**\r
549 Use Console Control to turn on GOP/UGA based Simple Text Out consoles. The GOP/UGA\r
550 Simple Text Out screens will now be synced up with all non GOP/UGA output devices\r
45e6322c 551\r
ed7752ec 552 @retval EFI_SUCCESS - GOP/UGA devices are back in text mode and synced up.\r
553 @retval EFI_UNSUPPORTED - Logo not found\r
554**/\r
45e6322c 555EFI_STATUS\r
556DisableQuietBoot (\r
557 VOID\r
558 )\r
45e6322c 559\r
45e6322c 560{\r
561 EFI_STATUS Status;\r
562 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
563\r
564 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
565 if (EFI_ERROR (Status)) {\r
566 return EFI_UNSUPPORTED;\r
567 }\r
568\r
569 return ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);\r
570}\r
571\r
572static EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors[16] = {\r
573 { 0x00, 0x00, 0x00, 0x00 },\r
574 { 0x98, 0x00, 0x00, 0x00 },\r
575 { 0x00, 0x98, 0x00, 0x00 },\r
576 { 0x98, 0x98, 0x00, 0x00 },\r
577 { 0x00, 0x00, 0x98, 0x00 },\r
578 { 0x98, 0x00, 0x98, 0x00 },\r
579 { 0x00, 0x98, 0x98, 0x00 },\r
580 { 0x98, 0x98, 0x98, 0x00 },\r
581 { 0x10, 0x10, 0x10, 0x00 },\r
582 { 0xff, 0x10, 0x10, 0x00 },\r
583 { 0x10, 0xff, 0x10, 0x00 },\r
584 { 0xff, 0xff, 0x10, 0x00 },\r
585 { 0x10, 0x10, 0xff, 0x00 },\r
586 { 0xf0, 0x10, 0xff, 0x00 },\r
587 { 0x10, 0xff, 0xff, 0x00 },\r
588 { 0xff, 0xff, 0xff, 0x00 }\r
589};\r
590\r
ed7752ec 591/**\r
45e6322c 592 Display string worker for: Print, PrintAt, IPrint, IPrintAt\r
593\r
ed7752ec 594 @param GraphicsOutput - Graphics output protocol interface\r
45e6322c 595\r
ed7752ec 596 @param UgaDraw - UGA draw protocol interface\r
67996c41 597\r
ed7752ec 598 @param Sto - Simple text out protocol interface\r
67996c41 599\r
ed7752ec 600 @param X - X coordinate to start printing\r
67996c41 601\r
ed7752ec 602 @param Y - Y coordinate to start printing\r
67996c41 603\r
ed7752ec 604 @param Foreground - Foreground color\r
67996c41 605\r
ed7752ec 606 @param Background - Background color\r
67996c41 607\r
ed7752ec 608 @param fmt - Format string\r
67996c41 609\r
ed7752ec 610 @param args - Print arguments\r
67996c41 611\r
45e6322c 612\r
ed7752ec 613 @retval EFI_SUCCESS - success\r
614 @retval EFI_OUT_OF_RESOURCES - out of resources\r
45e6322c 615\r
ed7752ec 616**/\r
617STATIC\r
618UINTN\r
619_IPrint (\r
620 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
621 IN EFI_UGA_DRAW_PROTOCOL *UgaDraw,\r
622 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Sto,\r
623 IN UINTN X,\r
624 IN UINTN Y,\r
625 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,\r
626 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background,\r
627 IN CHAR16 *fmt,\r
628 IN VA_LIST args\r
629 )\r
45e6322c 630\r
45e6322c 631{\r
62409219 632 VOID *Buffer;\r
633 EFI_STATUS Status;\r
634 UINT16 GlyphWidth;\r
635 UINT32 GlyphStatus;\r
636 UINT16 StringIndex;\r
637 UINTN Index;\r
638 CHAR16 *UnicodeWeight;\r
639 EFI_NARROW_GLYPH *Glyph;\r
640 EFI_HII_PROTOCOL *Hii;\r
641 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LineBuffer;\r
642 UINT32 HorizontalResolution;\r
643 UINT32 VerticalResolution;\r
644 UINT32 ColorDepth;\r
645 UINT32 RefreshRate;\r
646 UINTN BufferLen;\r
647 UINTN LineBufferLen;\r
648 UINTN BufferGlyphWidth;\r
45e6322c 649\r
650 GlyphStatus = 0;\r
b67754b9 651 HorizontalResolution = 0;\r
652 VerticalResolution = 0;\r
45e6322c 653\r
654 //\r
655 // For now, allocate an arbitrarily long buffer\r
656 //\r
657 Buffer = AllocateZeroPool (0x10000);\r
658 if (Buffer == NULL) {\r
659 return EFI_OUT_OF_RESOURCES;\r
660 }\r
67996c41 661\r
45e6322c 662 if (GraphicsOutput != NULL) {\r
663 HorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;\r
664 VerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;\r
8541adab 665 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
45e6322c 666 //\r
667 // Get the current mode information from the UGA Draw Protocol\r
668 //\r
669 UgaDraw->GetMode (UgaDraw, &HorizontalResolution, &VerticalResolution, &ColorDepth, &RefreshRate);\r
670 }\r
62409219 671 ASSERT ((HorizontalResolution != 0) && (VerticalResolution !=0));\r
45e6322c 672\r
62409219 673 LineBufferLen = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * HorizontalResolution * GLYPH_HEIGHT;\r
674 LineBuffer = AllocatePool (LineBufferLen);\r
45e6322c 675 if (LineBuffer == NULL) {\r
676 gBS->FreePool (Buffer);\r
677 return EFI_OUT_OF_RESOURCES;\r
678 }\r
679\r
680 Status = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, (VOID **) &Hii);\r
681 if (EFI_ERROR (Status)) {\r
682 goto Error;\r
683 }\r
684\r
685 UnicodeVSPrint (Buffer, 0x10000, fmt, args);\r
686\r
687 UnicodeWeight = (CHAR16 *) Buffer;\r
688\r
689 for (Index = 0; UnicodeWeight[Index] != 0; Index++) {\r
690 if (UnicodeWeight[Index] == CHAR_BACKSPACE ||\r
691 UnicodeWeight[Index] == CHAR_LINEFEED ||\r
692 UnicodeWeight[Index] == CHAR_CARRIAGE_RETURN) {\r
693 UnicodeWeight[Index] = 0;\r
694 }\r
695 }\r
696\r
62409219 697 BufferLen = StrLen (Buffer);\r
698\r
699 if (GLYPH_WIDTH * GLYPH_HEIGHT * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * BufferLen > LineBufferLen) {\r
700 Status = EFI_INVALID_PARAMETER;\r
701 goto Error;\r
702 }\r
703\r
704 for (Index = 0; Index < BufferLen; Index++) {\r
45e6322c 705 StringIndex = (UINT16) Index;\r
706 Status = Hii->GetGlyph (Hii, UnicodeWeight, &StringIndex, (UINT8 **) &Glyph, &GlyphWidth, &GlyphStatus);\r
707 if (EFI_ERROR (Status)) {\r
708 goto Error;\r
709 }\r
710\r
711 if (Foreground == NULL || Background == NULL) {\r
712 Status = Hii->GlyphToBlt (\r
713 Hii,\r
714 (UINT8 *) Glyph,\r
715 mEfiColors[Sto->Mode->Attribute & 0x0f],\r
716 mEfiColors[Sto->Mode->Attribute >> 4],\r
62409219 717 BufferLen,\r
45e6322c 718 GlyphWidth,\r
719 GLYPH_HEIGHT,\r
720 &LineBuffer[Index * GLYPH_WIDTH]\r
721 );\r
722 } else {\r
723 Status = Hii->GlyphToBlt (\r
724 Hii,\r
725 (UINT8 *) Glyph,\r
726 *Foreground,\r
727 *Background,\r
62409219 728 BufferLen,\r
45e6322c 729 GlyphWidth,\r
730 GLYPH_HEIGHT,\r
731 &LineBuffer[Index * GLYPH_WIDTH]\r
732 );\r
733 }\r
734 }\r
735\r
736 //\r
737 // Blt a character to the screen\r
738 //\r
62409219 739 BufferGlyphWidth = GLYPH_WIDTH * BufferLen;\r
45e6322c 740 if (GraphicsOutput != NULL) {\r
741 Status = GraphicsOutput->Blt (\r
742 GraphicsOutput,\r
743 LineBuffer,\r
744 EfiBltBufferToVideo,\r
745 0,\r
746 0,\r
747 X,\r
748 Y,\r
749 BufferGlyphWidth,\r
750 GLYPH_HEIGHT,\r
751 BufferGlyphWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
752 );\r
8541adab 753 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
45e6322c 754 Status = UgaDraw->Blt (\r
755 UgaDraw,\r
756 (EFI_UGA_PIXEL *) (UINTN) LineBuffer,\r
757 EfiUgaBltBufferToVideo,\r
758 0,\r
759 0,\r
760 X,\r
761 Y,\r
762 BufferGlyphWidth,\r
763 GLYPH_HEIGHT,\r
764 BufferGlyphWidth * sizeof (EFI_UGA_PIXEL)\r
765 );\r
8541adab 766 } else {\r
767 Status = EFI_UNSUPPORTED;\r
45e6322c 768 }\r
769\r
770Error:\r
771 gBS->FreePool (LineBuffer);\r
772 gBS->FreePool (Buffer);\r
773 return Status;\r
774}\r
775\r
ed7752ec 776/**\r
777 Prints a formatted unicode string to the default console\r
778\r
779 @param X - X coordinate to start printing\r
780\r
781 @param Y - Y coordinate to start printing\r
782\r
783 @param ForeGround - Foreground color\r
784\r
785 @param BackGround - Background color\r
786\r
787 @param Fmt - Format string\r
788\r
789 @param ... - Print arguments\r
45e6322c 790\r
ed7752ec 791\r
792 @retval Length of string printed to the console\r
793\r
794**/\r
45e6322c 795UINTN\r
796PrintXY (\r
797 IN UINTN X,\r
798 IN UINTN Y,\r
799 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ForeGround, OPTIONAL\r
800 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BackGround, OPTIONAL\r
801 IN CHAR16 *Fmt,\r
802 ...\r
803 )\r
45e6322c 804{\r
805 EFI_HANDLE Handle;\r
806\r
807 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
808 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
809 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Sto;\r
810 EFI_STATUS Status;\r
811 VA_LIST Args;\r
812\r
813 VA_START (Args, Fmt);\r
814\r
815 UgaDraw = NULL;\r
816\r
817 Handle = gST->ConsoleOutHandle;\r
818\r
819 Status = gBS->HandleProtocol (\r
820 Handle,\r
821 &gEfiGraphicsOutputProtocolGuid,\r
822 (VOID **) &GraphicsOutput\r
823 );\r
824\r
8541adab 825 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
45e6322c 826 GraphicsOutput = NULL;\r
827\r
828 Status = gBS->HandleProtocol (\r
829 Handle,\r
830 &gEfiUgaDrawProtocolGuid,\r
831 (VOID **) &UgaDraw\r
832 );\r
8541adab 833 }\r
45e6322c 834\r
8541adab 835 if (EFI_ERROR (Status)) {\r
836 return Status;\r
45e6322c 837 }\r
838\r
839 Status = gBS->HandleProtocol (\r
840 Handle,\r
841 &gEfiSimpleTextOutProtocolGuid,\r
842 (VOID **) &Sto\r
843 );\r
844\r
845 if (EFI_ERROR (Status)) {\r
846 return Status;\r
847 }\r
848\r
849 return _IPrint (GraphicsOutput, UgaDraw, Sto, X, Y, ForeGround, BackGround, Fmt, Args);\r
850}\r
ed7752ec 851\r