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