]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Library/GraphicsLib/Graphics.c
initialize local variable before use.
[mirror_edk2.git] / IntelFrameworkModulePkg / Library / GraphicsLib / Graphics.c
CommitLineData
3db51098 1/**@file\r
2 Support for Basic Graphics operations.\r
3\r
4 BugBug: Currently *.BMP files are supported. This will be replaced\r
5 when Tiano graphics format is supported.\r
6\r
45e6322c 7\r
67996c41 8Copyright (c) 2006, Intel Corporation\r
9All rights reserved. This program and the accompanying materials\r
10are licensed and made available under the terms and conditions of the BSD License\r
11which accompanies this distribution. The full text of the license may be found at\r
12http://opensource.org/licenses/bsd-license.php\r
13\r
14THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
15WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
45e6322c 16\r
3db51098 17**/\r
45e6322c 18\r
67996c41 19\r
20#include <PiDxe.h>\r
21\r
22#include <Protocol/SimpleTextOut.h>\r
23#include <Protocol/OEMBadging.h>\r
24#include <Protocol/ConsoleControl.h>\r
25#include <Protocol/GraphicsOutput.h>\r
26#include <Protocol/FirmwareVolume2.h>\r
27#include <Protocol/UgaDraw.h>\r
8e5b17b2 28#include <Protocol/FrameworkHii.h>\r
67996c41 29\r
30#include <Guid/Bmp.h>\r
31\r
32#include <Library/GraphicsLib.h>\r
33#include <Library/PrintLib.h>\r
34#include <Library/BaseLib.h>\r
35#include <Library/MemoryAllocationLib.h>\r
36#include <Library/UefiBootServicesTableLib.h>\r
62409219 37#include <Library/DebugLib.h>\r
8541adab 38#include <Library/PcdLib.h>\r
45e6322c 39\r
ed7752ec 40/**\r
45e6322c 41 Return the graphics image file named FileNameGuid into Image and return it's\r
42 size in ImageSize. All Firmware Volumes (FV) in the system are searched for the\r
43 file name.\r
44\r
ed7752ec 45 @param FileNameGuid - File Name of graphics file in the FV(s).\r
45e6322c 46\r
ed7752ec 47 @param Image - Pointer to pointer to return graphics image. If NULL, a\r
48 buffer will be allocated.\r
45e6322c 49\r
ed7752ec 50 @param ImageSize - Size of the graphics Image in bytes. Zero if no image found.\r
45e6322c 51\r
ed7752ec 52 @retval EFI_SUCCESS - Image and ImageSize are valid.\r
53 @retval EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size\r
54 @retval EFI_NOT_FOUND - FileNameGuid not found\r
45e6322c 55\r
ed7752ec 56**/\r
45e6322c 57\r
ed7752ec 58EFI_STATUS\r
59GetGraphicsBitMapFromFV (\r
60 IN EFI_GUID *FileNameGuid,\r
61 OUT VOID **Image,\r
62 OUT UINTN *ImageSize\r
63 )\r
45e6322c 64{\r
65 EFI_STATUS Status;\r
66 UINTN FvProtocolCount;\r
67 EFI_HANDLE *FvHandles;\r
507b36ca 68 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
45e6322c 69 UINTN Index;\r
70 UINT32 AuthenticationStatus;\r
71\r
72\r
73 Status = gBS->LocateHandleBuffer (\r
74 ByProtocol,\r
507b36ca 75 &gEfiFirmwareVolume2ProtocolGuid,\r
45e6322c 76 NULL,\r
77 &FvProtocolCount,\r
78 &FvHandles\r
79 );\r
80 if (EFI_ERROR (Status)) {\r
81 return EFI_NOT_FOUND;\r
82 }\r
83\r
84 for (Index = 0; Index < FvProtocolCount; Index++) {\r
85 Status = gBS->HandleProtocol (\r
86 FvHandles[Index],\r
507b36ca 87 &gEfiFirmwareVolume2ProtocolGuid,\r
45e6322c 88 (VOID **) &Fv\r
89 );\r
90\r
91 //\r
92 // Assuming Image and ImageSize are correct on input.\r
93 //\r
94 Status = Fv->ReadSection (\r
95 Fv,\r
96 FileNameGuid,\r
97 EFI_SECTION_RAW,\r
98 0,\r
99 Image,\r
100 ImageSize,\r
101 &AuthenticationStatus\r
102 );\r
103 if (!EFI_ERROR (Status)) {\r
104 return EFI_SUCCESS;\r
105 } else if (Status == EFI_BUFFER_TOO_SMALL) {\r
106 //\r
107 // ImageSize updated to needed size so return\r
108 //\r
109 return EFI_BUFFER_TOO_SMALL;\r
110 }\r
111 }\r
112\r
113 return EFI_NOT_FOUND;\r
114}\r
115\r
ed7752ec 116/**\r
62409219 117 Convert a *.BMP graphics image to a GOP/UGA blt buffer. If a NULL Blt buffer\r
118 is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt\r
45e6322c 119 buffer is passed in it will be used if it is big enough.\r
120\r
ed7752ec 121 @param BmpImage - Pointer to BMP file\r
45e6322c 122\r
ed7752ec 123 @param BmpImageSize - Number of bytes in BmpImage\r
45e6322c 124\r
ed7752ec 125 @param GopBlt - Buffer containing GOP version of BmpImage.\r
45e6322c 126\r
ed7752ec 127 @param GopBltSize - Size of GopBlt in bytes.\r
45e6322c 128\r
ed7752ec 129 @param PixelHeight - Height of GopBlt/BmpImage in pixels\r
45e6322c 130\r
ed7752ec 131 @param PixelWidth - Width of GopBlt/BmpImage in pixels\r
45e6322c 132\r
45e6322c 133\r
ed7752ec 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
138 @retval EFI_OUT_OF_RESOURCES - No enough buffer to allocate\r
45e6322c 139\r
ed7752ec 140**/\r
141STATIC\r
142EFI_STATUS\r
143ConvertBmpToGopBlt (\r
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
150 )\r
45e6322c 151\r
45e6322c 152{\r
153 UINT8 *Image;\r
154 UINT8 *ImageHeader;\r
155 BMP_IMAGE_HEADER *BmpHeader;\r
156 BMP_COLOR_MAP *BmpColorMap;\r
157 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
158 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
159 UINTN BltBufferSize;\r
160 UINTN Index;\r
161 UINTN Height;\r
162 UINTN Width;\r
163 UINTN ImageIndex;\r
164 BOOLEAN IsAllocated;\r
67996c41 165\r
45e6322c 166 BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;\r
167 if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {\r
168 return EFI_UNSUPPORTED;\r
169 }\r
170\r
171 if (BmpHeader->CompressionType != 0) {\r
172 return EFI_UNSUPPORTED;\r
173 }\r
174\r
175 //\r
176 // Calculate Color Map offset in the image.\r
177 //\r
178 Image = BmpImage;\r
179 BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));\r
180\r
181 //\r
182 // Calculate graphics image data address in the image\r
183 //\r
184 Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;\r
185 ImageHeader = Image;\r
186\r
187 BltBufferSize = BmpHeader->PixelWidth * BmpHeader->PixelHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
188 IsAllocated = FALSE;\r
189 if (*GopBlt == NULL) {\r
190 *GopBltSize = BltBufferSize;\r
191 *GopBlt = AllocatePool (*GopBltSize);\r
192 IsAllocated = TRUE;\r
193 if (*GopBlt == NULL) {\r
194 return EFI_OUT_OF_RESOURCES;\r
195 }\r
196 } else {\r
197 if (*GopBltSize < BltBufferSize) {\r
198 *GopBltSize = BltBufferSize;\r
199 return EFI_BUFFER_TOO_SMALL;\r
200 }\r
201 }\r
202\r
203 *PixelWidth = BmpHeader->PixelWidth;\r
204 *PixelHeight = BmpHeader->PixelHeight;\r
205\r
206 //\r
207 // Convert image from BMP to Blt buffer format\r
208 //\r
209 BltBuffer = *GopBlt;\r
210 for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {\r
211 Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];\r
212 for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {\r
213 switch (BmpHeader->BitPerPixel) {\r
214 case 1:\r
215 //\r
216 // Convert 1bit BMP to 24-bit color\r
217 //\r
218 for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {\r
219 Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;\r
220 Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;\r
221 Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;\r
222 Blt++;\r
223 Width++;\r
224 }\r
225\r
226 Blt --;\r
227 Width --;\r
228 break;\r
67996c41 229\r
45e6322c 230 case 4:\r
231 //\r
232 // Convert BMP Palette to 24-bit color\r
233 //\r
234 Index = (*Image) >> 4;\r
235 Blt->Red = BmpColorMap[Index].Red;\r
236 Blt->Green = BmpColorMap[Index].Green;\r
237 Blt->Blue = BmpColorMap[Index].Blue;\r
238 if (Width < (BmpHeader->PixelWidth - 1)) {\r
239 Blt++;\r
240 Width++;\r
241 Index = (*Image) & 0x0f;\r
242 Blt->Red = BmpColorMap[Index].Red;\r
243 Blt->Green = BmpColorMap[Index].Green;\r
244 Blt->Blue = BmpColorMap[Index].Blue;\r
245 }\r
246 break;\r
247\r
248 case 8:\r
249 //\r
250 // Convert BMP Palette to 24-bit color\r
251 //\r
252 Blt->Red = BmpColorMap[*Image].Red;\r
253 Blt->Green = BmpColorMap[*Image].Green;\r
254 Blt->Blue = BmpColorMap[*Image].Blue;\r
255 break;\r
256\r
257 case 24:\r
258 Blt->Blue = *Image++;\r
259 Blt->Green = *Image++;\r
260 Blt->Red = *Image;\r
261 break;\r
262\r
263 default:\r
264 if (IsAllocated) {\r
265 gBS->FreePool (*GopBlt);\r
266 *GopBlt = NULL;\r
267 }\r
268 return EFI_UNSUPPORTED;\r
269 break;\r
270 };\r
271\r
272 }\r
273\r
274 ImageIndex = (UINTN) (Image - ImageHeader);\r
275 if ((ImageIndex % 4) != 0) {\r
276 //\r
277 // Bmp Image starts each row on a 32-bit boundary!\r
278 //\r
279 Image = Image + (4 - (ImageIndex % 4));\r
280 }\r
281 }\r
282\r
283 return EFI_SUCCESS;\r
284}\r
285\r
ed7752ec 286/**\r
67996c41 287 Use Console Control Protocol to lock the Console In Spliter virtual handle.\r
45e6322c 288 This is the ConInHandle and ConIn handle in the EFI system table. All key\r
289 presses will be ignored until the Password is typed in. The only way to\r
290 disable the password is to type it in to a ConIn device.\r
291\r
ed7752ec 292 @param Password - Password used to lock ConIn device\r
45e6322c 293\r
ed7752ec 294 @retval EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo\r
45e6322c 295 displayed.\r
ed7752ec 296 @retval EFI_UNSUPPORTED - Logo not found\r
45e6322c 297\r
ed7752ec 298**/\r
299EFI_STATUS\r
300LockKeyboards (\r
301 IN CHAR16 *Password\r
302 )\r
45e6322c 303{\r
304 EFI_STATUS Status;\r
305 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
306\r
307 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
308 if (EFI_ERROR (Status)) {\r
309 return EFI_UNSUPPORTED;\r
310 }\r
311\r
312 Status = ConsoleControl->LockStdIn (ConsoleControl, Password);\r
313 return Status;\r
314}\r
315\r
ed7752ec 316/**\r
45e6322c 317 Use Console Control to turn off UGA based Simple Text Out consoles from going\r
318 to the UGA device. Put up LogoFile on every UGA device that is a console\r
319\r
ed7752ec 320 @param LogoFile - File name of logo to display on the center of the screen.\r
45e6322c 321\r
ed7752ec 322 @retval EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo\r
323 displayed.\r
324 @retval EFI_UNSUPPORTED - Logo not found\r
45e6322c 325\r
ed7752ec 326**/\r
327EFI_STATUS\r
328EnableQuietBoot (\r
329 IN EFI_GUID *LogoFile\r
330 )\r
45e6322c 331\r
45e6322c 332{\r
333 EFI_STATUS Status;\r
334 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
335 EFI_OEM_BADGING_PROTOCOL *Badging;\r
336 UINT32 SizeOfX;\r
337 UINT32 SizeOfY;\r
338 INTN DestX;\r
339 INTN DestY;\r
340 UINT8 *ImageData;\r
341 UINTN ImageSize;\r
342 UINTN BltSize;\r
343 UINT32 Instance;\r
344 EFI_BADGING_FORMAT Format;\r
345 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;\r
346 UINTN CoordinateX;\r
347 UINTN CoordinateY;\r
348 UINTN Height;\r
349 UINTN Width;\r
350 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
351 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
352 UINT32 ColorDepth;\r
353 UINT32 RefreshRate;\r
354 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
355\r
356 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
357 if (EFI_ERROR (Status)) {\r
358 return EFI_UNSUPPORTED;\r
359 }\r
360\r
361 UgaDraw = NULL;\r
362 //\r
363 // Try to open GOP first\r
364 //\r
67996c41 365 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);\r
8541adab 366 if (EFI_ERROR(Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
45e6322c 367 GraphicsOutput = NULL;\r
368 //\r
369 // Open GOP failed, try to open UGA\r
370 //\r
371 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);\r
8541adab 372 }\r
373 if (EFI_ERROR (Status)) {\r
374 return EFI_UNSUPPORTED;\r
45e6322c 375 }\r
376\r
377 Badging = NULL;\r
378 Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);\r
379\r
380 ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics);\r
381\r
382 if (GraphicsOutput != NULL) {\r
383 SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
384 SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
8541adab 385 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
45e6322c 386 Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);\r
387 if (EFI_ERROR (Status)) {\r
388 return EFI_UNSUPPORTED;\r
389 }\r
695f7e98 390 } else {\r
391 return EFI_UNSUPPORTED;\r
45e6322c 392 }\r
393\r
394 Instance = 0;\r
395 while (1) {\r
396 ImageData = NULL;\r
397 ImageSize = 0;\r
398\r
399 if (Badging != NULL) {\r
400 Status = Badging->GetImage (\r
401 Badging,\r
402 &Instance,\r
403 &Format,\r
404 &ImageData,\r
405 &ImageSize,\r
406 &Attribute,\r
407 &CoordinateX,\r
408 &CoordinateY\r
409 );\r
410 if (EFI_ERROR (Status)) {\r
411 return Status;\r
412 }\r
413\r
414 //\r
415 // Currently only support BMP format\r
416 //\r
417 if (Format != EfiBadgingFormatBMP) {\r
418 gBS->FreePool (ImageData);\r
419 continue;\r
420 }\r
421 } else {\r
422 Status = GetGraphicsBitMapFromFV (LogoFile, (VOID **) &ImageData, &ImageSize);\r
423 if (EFI_ERROR (Status)) {\r
424 return EFI_UNSUPPORTED;\r
425 }\r
426\r
427 CoordinateX = 0;\r
428 CoordinateY = 0;\r
429 Attribute = EfiBadgingDisplayAttributeCenter;\r
430 }\r
431\r
432 Blt = NULL;\r
433 BltSize = 0;\r
434 Status = ConvertBmpToGopBlt (\r
435 ImageData,\r
436 ImageSize,\r
437 (VOID**)&Blt,\r
438 &BltSize,\r
439 &Height,\r
440 &Width\r
441 );\r
442 if (EFI_ERROR (Status)) {\r
443 gBS->FreePool (ImageData);\r
444 if (Badging == NULL) {\r
445 return Status;\r
446 } else {\r
447 continue;\r
448 }\r
449 }\r
450\r
451 switch (Attribute) {\r
452 case EfiBadgingDisplayAttributeLeftTop:\r
453 DestX = CoordinateX;\r
454 DestY = CoordinateY;\r
455 break;\r
456\r
457 case EfiBadgingDisplayAttributeCenterTop:\r
458 DestX = (SizeOfX - Width) / 2;\r
459 DestY = CoordinateY;\r
460 break;\r
461\r
462 case EfiBadgingDisplayAttributeRightTop:\r
463 DestX = (SizeOfX - Width - CoordinateX);\r
464 DestY = CoordinateY;;\r
465 break;\r
466\r
467 case EfiBadgingDisplayAttributeCenterRight:\r
468 DestX = (SizeOfX - Width - CoordinateX);\r
469 DestY = (SizeOfY - Height) / 2;\r
470 break;\r
471\r
472 case EfiBadgingDisplayAttributeRightBottom:\r
473 DestX = (SizeOfX - Width - CoordinateX);\r
474 DestY = (SizeOfY - Height - CoordinateY);\r
475 break;\r
476\r
477 case EfiBadgingDisplayAttributeCenterBottom:\r
478 DestX = (SizeOfX - Width) / 2;\r
479 DestY = (SizeOfY - Height - CoordinateY);\r
480 break;\r
481\r
482 case EfiBadgingDisplayAttributeLeftBottom:\r
483 DestX = CoordinateX;\r
484 DestY = (SizeOfY - Height - CoordinateY);\r
485 break;\r
486\r
487 case EfiBadgingDisplayAttributeCenterLeft:\r
488 DestX = CoordinateX;\r
489 DestY = (SizeOfY - Height) / 2;\r
490 break;\r
491\r
492 case EfiBadgingDisplayAttributeCenter:\r
493 DestX = (SizeOfX - Width) / 2;\r
494 DestY = (SizeOfY - Height) / 2;\r
495 break;\r
496\r
497 default:\r
498 DestX = CoordinateX;\r
499 DestY = CoordinateY;\r
500 break;\r
501 }\r
502\r
503 if ((DestX >= 0) && (DestY >= 0)) {\r
504 if (GraphicsOutput != NULL) {\r
505 Status = GraphicsOutput->Blt (\r
506 GraphicsOutput,\r
507 Blt,\r
508 EfiBltBufferToVideo,\r
509 0,\r
510 0,\r
511 (UINTN) DestX,\r
512 (UINTN) DestY,\r
513 Width,\r
514 Height,\r
515 Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
516 );\r
8541adab 517 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
45e6322c 518 Status = UgaDraw->Blt (\r
519 UgaDraw,\r
520 (EFI_UGA_PIXEL *) Blt,\r
521 EfiUgaBltBufferToVideo,\r
522 0,\r
523 0,\r
524 (UINTN) DestX,\r
525 (UINTN) DestY,\r
526 Width,\r
527 Height,\r
528 Width * sizeof (EFI_UGA_PIXEL)\r
529 );\r
8541adab 530 } else {\r
531 Status = EFI_UNSUPPORTED;\r
45e6322c 532 }\r
533 }\r
534\r
535 gBS->FreePool (ImageData);\r
536 gBS->FreePool (Blt);\r
537\r
538 if (Badging == NULL) {\r
539 break;\r
540 }\r
541 }\r
542\r
543 return Status;\r
544}\r
545\r
ed7752ec 546/**\r
547 Use Console Control to turn on GOP/UGA based Simple Text Out consoles. The GOP/UGA\r
548 Simple Text Out screens will now be synced up with all non GOP/UGA output devices\r
45e6322c 549\r
ed7752ec 550 @retval EFI_SUCCESS - GOP/UGA devices are back in text mode and synced up.\r
551 @retval EFI_UNSUPPORTED - Logo not found\r
552**/\r
45e6322c 553EFI_STATUS\r
554DisableQuietBoot (\r
555 VOID\r
556 )\r
45e6322c 557\r
45e6322c 558{\r
559 EFI_STATUS Status;\r
560 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
561\r
562 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
563 if (EFI_ERROR (Status)) {\r
564 return EFI_UNSUPPORTED;\r
565 }\r
566\r
567 return ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);\r
568}\r
569\r
570static EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors[16] = {\r
571 { 0x00, 0x00, 0x00, 0x00 },\r
572 { 0x98, 0x00, 0x00, 0x00 },\r
573 { 0x00, 0x98, 0x00, 0x00 },\r
574 { 0x98, 0x98, 0x00, 0x00 },\r
575 { 0x00, 0x00, 0x98, 0x00 },\r
576 { 0x98, 0x00, 0x98, 0x00 },\r
577 { 0x00, 0x98, 0x98, 0x00 },\r
578 { 0x98, 0x98, 0x98, 0x00 },\r
579 { 0x10, 0x10, 0x10, 0x00 },\r
580 { 0xff, 0x10, 0x10, 0x00 },\r
581 { 0x10, 0xff, 0x10, 0x00 },\r
582 { 0xff, 0xff, 0x10, 0x00 },\r
583 { 0x10, 0x10, 0xff, 0x00 },\r
584 { 0xf0, 0x10, 0xff, 0x00 },\r
585 { 0x10, 0xff, 0xff, 0x00 },\r
586 { 0xff, 0xff, 0xff, 0x00 }\r
587};\r
588\r
ed7752ec 589/**\r
45e6322c 590 Display string worker for: Print, PrintAt, IPrint, IPrintAt\r
591\r
ed7752ec 592 @param GraphicsOutput - Graphics output protocol interface\r
45e6322c 593\r
ed7752ec 594 @param UgaDraw - UGA draw protocol interface\r
67996c41 595\r
ed7752ec 596 @param Sto - Simple text out protocol interface\r
67996c41 597\r
ed7752ec 598 @param X - X coordinate to start printing\r
67996c41 599\r
ed7752ec 600 @param Y - Y coordinate to start printing\r
67996c41 601\r
ed7752ec 602 @param Foreground - Foreground color\r
67996c41 603\r
ed7752ec 604 @param Background - Background color\r
67996c41 605\r
ed7752ec 606 @param fmt - Format string\r
67996c41 607\r
ed7752ec 608 @param args - Print arguments\r
67996c41 609\r
45e6322c 610\r
ed7752ec 611 @retval EFI_SUCCESS - success\r
612 @retval EFI_OUT_OF_RESOURCES - out of resources\r
45e6322c 613\r
ed7752ec 614**/\r
615STATIC\r
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