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