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