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