e86b493db1f9462ef2ecd7a77abe50b777cdb902
[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 \r
42 STATIC 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
62 EFI_STATUS\r
63 GetGraphicsBitMapFromFV (\r
64   IN  EFI_GUID      *FileNameGuid,\r
65   OUT VOID          **Image,\r
66   OUT UINTN         *ImageSize\r
67   )\r
68 /*++\r
69 \r
70 Routine 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
76 Arguments:\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
86 Returns:\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
97 EFI_STATUS\r
98 GetGraphicsBitMapFromFVEx (\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
106 Routine 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
112 Arguments:\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
126 Returns: \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
134   return PiLibGetSectionFromAnyFv (\r
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
144 EFI_STATUS\r
145 ConvertBmpToGopBlt (\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
155 Routine 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
161 Arguments:\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
176 Returns:\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
320 EFI_STATUS\r
321 LockKeyboards (\r
322   IN  CHAR16    *Password\r
323   )\r
324 /*++\r
325 \r
326 Routine 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
332 Arguments:\r
333   Password - Password used to lock ConIn device\r
334 \r
335 \r
336 Returns:\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
357 EFI_STATUS\r
358 EnableQuietBoot (\r
359   IN  EFI_GUID  *LogoFile\r
360   )\r
361 /*++\r
362 \r
363 Routine 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
368 Arguments:\r
369 \r
370   LogoFile - File name of logo to display on the center of the screen.\r
371 \r
372 \r
373 Returns: \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
384 EFI_STATUS\r
385 EnableQuietBootEx (\r
386   IN  EFI_GUID    *LogoFile,\r
387   IN  EFI_HANDLE  ImageHandle\r
388   )\r
389 /*++\r
390 \r
391 Routine 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
396 Arguments:\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
404 Returns: \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
459   Status = ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics);\r
460   if (EFI_ERROR (Status)) {\r
461     return EFI_UNSUPPORTED;\r
462   }\r
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
624 EFI_STATUS\r
625 DisableQuietBoot (\r
626   VOID\r
627   )\r
628 /*++\r
629 \r
630 Routine 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
635 Arguments:\r
636 \r
637   NONE\r
638 \r
639 Returns:\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
657 UINTN\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
671 Routine Description:\r
672 \r
673   Display string worker for: Print, PrintAt, IPrint, IPrintAt\r
674 \r
675 Arguments:\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
695 Returns: \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
809 Error:\r
810   SafeFreePool (Blt);\r
811   SafeFreePool (FontInfo);\r
812   gBS->FreePool (Buffer);\r
813   return Status;\r
814 }\r
815 \r
816 UINTN\r
817 PrintXY (\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
827 Routine Description:\r
828 \r
829     Prints a formatted unicode string to the default console\r
830 \r
831 Arguments:\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
845 Returns:\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