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