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