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