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