01c612abd339bfc258e85c6070324ddf1be64b75
[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 ConvertBmpToUgaBlt (
111 IN VOID *BmpImage,
112 IN UINTN BmpImageSize,
113 IN OUT VOID **UgaBlt,
114 IN OUT UINTN *UgaBltSize,
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_UGA_PIXEL *BltBuffer;
156 EFI_UGA_PIXEL *Blt;
157 UINTN BltBufferSize;
158 UINTN Index;
159 UINTN Height;
160 UINTN Width;
161 UINTN ImageIndex;
162
163 BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;
164 if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {
165 return EFI_UNSUPPORTED;
166 }
167
168 if (BmpHeader->CompressionType != 0) {
169 return EFI_UNSUPPORTED;
170 }
171
172 //
173 // Calculate Color Map offset in the image.
174 //
175 Image = BmpImage;
176 BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));
177
178 //
179 // Calculate graphics image data address in the image
180 //
181 Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;
182 ImageHeader = Image;
183
184 BltBufferSize = BmpHeader->PixelWidth * BmpHeader->PixelHeight * sizeof (EFI_UGA_PIXEL);
185 if (*UgaBlt == NULL) {
186 *UgaBltSize = BltBufferSize;
187 *UgaBlt = AllocatePool (*UgaBltSize);
188 if (*UgaBlt == NULL) {
189 return EFI_OUT_OF_RESOURCES;
190 }
191 } else {
192 if (*UgaBltSize < BltBufferSize) {
193 *UgaBltSize = BltBufferSize;
194 return EFI_BUFFER_TOO_SMALL;
195 }
196 }
197
198 *PixelWidth = BmpHeader->PixelWidth;
199 *PixelHeight = BmpHeader->PixelHeight;
200
201 //
202 // Convert image from BMP to Blt buffer format
203 //
204 BltBuffer = *UgaBlt;
205 for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {
206 Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];
207 for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {
208 switch (BmpHeader->BitPerPixel) {
209 case 1:
210 //
211 // Convert 1bit BMP to 24-bit color
212 //
213 for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {
214 Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;
215 Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;
216 Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;
217 Blt++;
218 Width++;
219 }
220
221 Blt --;
222 Width --;
223 break;
224
225 case 4:
226 //
227 // Convert BMP Palette to 24-bit color
228 //
229 Index = (*Image) >> 4;
230 Blt->Red = BmpColorMap[Index].Red;
231 Blt->Green = BmpColorMap[Index].Green;
232 Blt->Blue = BmpColorMap[Index].Blue;
233 if (Width < (BmpHeader->PixelWidth - 1)) {
234 Blt++;
235 Width++;
236 Index = (*Image) & 0x0f;
237 Blt->Red = BmpColorMap[Index].Red;
238 Blt->Green = BmpColorMap[Index].Green;
239 Blt->Blue = BmpColorMap[Index].Blue;
240 }
241 break;
242
243 case 8:
244 //
245 // Convert BMP Palette to 24-bit color
246 //
247 Blt->Red = BmpColorMap[*Image].Red;
248 Blt->Green = BmpColorMap[*Image].Green;
249 Blt->Blue = BmpColorMap[*Image].Blue;
250 break;
251
252 case 24:
253 Blt->Blue = *Image++;
254 Blt->Green = *Image++;
255 Blt->Red = *Image;
256 break;
257
258 default:
259 return EFI_UNSUPPORTED;
260 break;
261 };
262
263 }
264
265 ImageIndex = (UINTN) (Image - ImageHeader);
266 if ((ImageIndex % 4) != 0) {
267 //
268 // Bmp Image starts each row on a 32-bit boundary!
269 //
270 Image = Image + (4 - (ImageIndex % 4));
271 }
272 }
273
274 return EFI_SUCCESS;
275 }
276
277
278 EFI_STATUS
279 LockKeyboards (
280 IN CHAR16 *Password
281 )
282 /*++
283
284 Routine Description:
285 Use Console Control Protocol to lock the Console In Spliter virtual handle.
286 This is the ConInHandle and ConIn handle in the EFI system table. All key
287 presses will be ignored until the Password is typed in. The only way to
288 disable the password is to type it in to a ConIn device.
289
290 Arguments:
291 Password - Password used to lock ConIn device
292
293
294 Returns:
295
296 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo
297 displayed.
298 EFI_UNSUPPORTED - Logo not found
299
300 --*/
301 {
302 EFI_STATUS Status;
303 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;
304
305 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);
306 if (EFI_ERROR (Status)) {
307 return EFI_UNSUPPORTED;
308 }
309
310 Status = ConsoleControl->LockStdIn (ConsoleControl, Password);
311 return Status;
312 }
313
314
315 EFI_STATUS
316 EnableQuietBoot (
317 IN EFI_GUID *LogoFile
318 )
319 /*++
320
321 Routine Description:
322
323 Use Console Control to turn off UGA based Simple Text Out consoles from going
324 to the UGA device. Put up LogoFile on every UGA device that is a console
325
326 Arguments:
327
328 LogoFile - File name of logo to display on the center of the screen.
329
330
331 Returns:
332
333 EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo
334 displayed.
335 EFI_UNSUPPORTED - Logo not found
336
337 --*/
338 {
339 EFI_STATUS Status;
340 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;
341 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
342 EFI_OEM_BADGING_PROTOCOL *Badging;
343 UINT32 SizeOfX;
344 UINT32 SizeOfY;
345 UINT32 ColorDepth;
346 UINT32 RefreshRate;
347 INTN DestX;
348 INTN DestY;
349
350 UINT8 *ImageData;
351 UINTN ImageSize;
352 EFI_UGA_PIXEL *UgaBlt;
353 UINTN UgaBltSize;
354
355 UINT32 Instance;
356 EFI_BADGING_FORMAT Format;
357 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;
358 UINTN CoordinateX;
359 UINTN CoordinateY;
360 UINTN Height;
361 UINTN Width;
362
363 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);
364 if (EFI_ERROR (Status)) {
365 return EFI_UNSUPPORTED;
366 }
367
368 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);
369 if (EFI_ERROR (Status)) {
370 return EFI_UNSUPPORTED;
371 }
372
373 Badging = NULL;
374 Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);
375
376 ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics);
377
378 Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);
379 if (EFI_ERROR (Status)) {
380 return EFI_UNSUPPORTED;
381 }
382
383 Instance = 0;
384 while (1) {
385 ImageData = NULL;
386 ImageSize = 0;
387
388 if (Badging != NULL) {
389 Status = Badging->GetImage (
390 Badging,
391 &Instance,
392 &Format,
393 &ImageData,
394 &ImageSize,
395 &Attribute,
396 &CoordinateX,
397 &CoordinateY
398 );
399 if (EFI_ERROR (Status)) {
400 return Status;
401 }
402
403 //
404 // Currently only support BMP format
405 //
406 if (Format != EfiBadgingFormatBMP) {
407 gBS->FreePool (ImageData);
408 continue;
409 }
410 } else {
411 Status = GetGraphicsBitMapFromFV (LogoFile, (VOID **) &ImageData, &ImageSize);
412 if (EFI_ERROR (Status)) {
413 return EFI_UNSUPPORTED;
414 }
415
416 CoordinateX = 0;
417 CoordinateY = 0;
418 Attribute = EfiBadgingDisplayAttributeCenter;
419 }
420
421 UgaBlt = NULL;
422 Status = ConvertBmpToUgaBlt (
423 ImageData,
424 ImageSize,
425 (VOID **) &UgaBlt,
426 &UgaBltSize,
427 &Height,
428 &Width
429 );
430 if (EFI_ERROR (Status)) {
431 gBS->FreePool (ImageData);
432 continue;
433 }
434
435 switch (Attribute) {
436 case EfiBadgingDisplayAttributeLeftTop:
437 DestX = CoordinateX;
438 DestY = CoordinateY;
439 break;
440
441 case EfiBadgingDisplayAttributeCenterTop:
442 DestX = (SizeOfX - Width) / 2;
443 DestY = CoordinateY;
444 break;
445
446 case EfiBadgingDisplayAttributeRightTop:
447 DestX = (SizeOfX - Width - CoordinateX);
448 DestY = CoordinateY;;
449 break;
450
451 case EfiBadgingDisplayAttributeCenterRight:
452 DestX = (SizeOfX - Width - CoordinateX);
453 DestY = (SizeOfY - Height) / 2;
454 break;
455
456 case EfiBadgingDisplayAttributeRightBottom:
457 DestX = (SizeOfX - Width - CoordinateX);
458 DestY = (SizeOfY - Height - CoordinateY);
459 break;
460
461 case EfiBadgingDisplayAttributeCenterBottom:
462 DestX = (SizeOfX - Width) / 2;
463 DestY = (SizeOfY - Height - CoordinateY);
464 break;
465
466 case EfiBadgingDisplayAttributeLeftBottom:
467 DestX = CoordinateX;
468 DestY = (SizeOfY - Height - CoordinateY);
469 break;
470
471 case EfiBadgingDisplayAttributeCenterLeft:
472 DestX = CoordinateX;
473 DestY = (SizeOfY - Height) / 2;
474 break;
475
476 case EfiBadgingDisplayAttributeCenter:
477 DestX = (SizeOfX - Width) / 2;
478 DestY = (SizeOfY - Height) / 2;
479 break;
480
481 default:
482 DestX = CoordinateX;
483 DestY = CoordinateY;
484 break;
485 }
486
487 if ((DestX >= 0) && (DestY >= 0)) {
488 Status = UgaDraw->Blt (
489 UgaDraw,
490 UgaBlt,
491 EfiUgaBltBufferToVideo,
492 0,
493 0,
494 (UINTN) DestX,
495 (UINTN) DestY,
496 Width,
497 Height,
498 Width * sizeof (EFI_UGA_PIXEL)
499 );
500 }
501
502 gBS->FreePool (ImageData);
503 gBS->FreePool (UgaBlt);
504
505 if (Badging == NULL) {
506 break;
507 }
508 }
509
510 return Status;
511 }
512
513
514 EFI_STATUS
515 DisableQuietBoot (
516 VOID
517 )
518 /*++
519
520 Routine Description:
521
522 Use Console Control to turn on UGA based Simple Text Out consoles. The UGA
523 Simple Text Out screens will now be synced up with all non UGA output devices
524
525 Arguments:
526
527 NONE
528
529 Returns:
530
531 EFI_SUCCESS - UGA devices are back in text mode and synced up.
532 EFI_UNSUPPORTED - Logo not found
533
534 --*/
535 {
536 EFI_STATUS Status;
537 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;
538
539 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);
540 if (EFI_ERROR (Status)) {
541 return EFI_UNSUPPORTED;
542 }
543
544 return ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);
545 }
546
547 static EFI_UGA_PIXEL mEfiColors[16] = {
548 { 0x00, 0x00, 0x00, 0x00 },
549 { 0x98, 0x00, 0x00, 0x00 },
550 { 0x00, 0x98, 0x00, 0x00 },
551 { 0x98, 0x98, 0x00, 0x00 },
552 { 0x00, 0x00, 0x98, 0x00 },
553 { 0x98, 0x00, 0x98, 0x00 },
554 { 0x00, 0x98, 0x98, 0x00 },
555 { 0x98, 0x98, 0x98, 0x00 },
556 { 0x10, 0x10, 0x10, 0x00 },
557 { 0xff, 0x10, 0x10, 0x00 },
558 { 0x10, 0xff, 0x10, 0x00 },
559 { 0xff, 0xff, 0x10, 0x00 },
560 { 0x10, 0x10, 0xff, 0x00 },
561 { 0xf0, 0x10, 0xff, 0x00 },
562 { 0x10, 0xff, 0xff, 0x00 },
563 { 0xff, 0xff, 0xff, 0x00 }
564 };
565
566 STATIC
567 UINTN
568 _IPrint (
569 IN EFI_UGA_DRAW_PROTOCOL *UgaDraw,
570 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *Sto,
571 IN UINTN X,
572 IN UINTN Y,
573 IN EFI_UGA_PIXEL *Foreground,
574 IN EFI_UGA_PIXEL *Background,
575 IN CHAR16 *fmt,
576 IN VA_LIST args
577 )
578 /*++
579
580 Routine Description:
581
582 Display string worker for: Print, PrintAt, IPrint, IPrintAt
583
584 Arguments:
585
586 UgaDraw - UGA draw protocol interface
587
588 Sto - Simple text out protocol interface
589
590 X - X coordinate to start printing
591
592 Y - Y coordinate to start printing
593
594 Foreground - Foreground color
595
596 Background - Background color
597
598 fmt - Format string
599
600 args - Print arguments
601
602 Returns:
603
604 EFI_SUCCESS - success
605 EFI_OUT_OF_RESOURCES - out of resources
606
607 --*/
608 {
609 VOID *Buffer;
610 EFI_STATUS Status;
611 UINT16 GlyphWidth;
612 UINT32 GlyphStatus;
613 UINT16 StringIndex;
614 UINTN Index;
615 CHAR16 *UnicodeWeight;
616 EFI_NARROW_GLYPH *Glyph;
617 EFI_HII_PROTOCOL *Hii;
618 EFI_UGA_PIXEL *LineBuffer;
619 UINT32 HorizontalResolution;
620 UINT32 VerticalResolution;
621 UINT32 ColorDepth;
622 UINT32 RefreshRate;
623
624 GlyphStatus = 0;
625
626 //
627 // For now, allocate an arbitrarily long buffer
628 //
629 Buffer = AllocateZeroPool (0x10000);
630 if (Buffer == NULL) {
631 return EFI_OUT_OF_RESOURCES;
632 }
633
634 UgaDraw->GetMode (UgaDraw, &HorizontalResolution, &VerticalResolution, &ColorDepth, &RefreshRate);
635
636 LineBuffer = AllocatePool (sizeof (EFI_UGA_PIXEL) * HorizontalResolution * GLYPH_WIDTH * GLYPH_HEIGHT);
637 if (LineBuffer == NULL) {
638 gBS->FreePool (Buffer);
639 return EFI_OUT_OF_RESOURCES;
640 }
641
642 Status = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, (VOID **) &Hii);
643 if (EFI_ERROR (Status)) {
644 goto Error;
645 }
646
647 UnicodeVSPrint (Buffer, 0x10000, fmt, args);
648
649 UnicodeWeight = (CHAR16 *) Buffer;
650
651 for (Index = 0; UnicodeWeight[Index] != 0; Index++) {
652 if (UnicodeWeight[Index] == CHAR_BACKSPACE ||
653 UnicodeWeight[Index] == CHAR_LINEFEED ||
654 UnicodeWeight[Index] == CHAR_CARRIAGE_RETURN) {
655 UnicodeWeight[Index] = 0;
656 }
657 }
658
659 for (Index = 0; Index < StrLen (Buffer); Index++) {
660 StringIndex = (UINT16) Index;
661 Status = Hii->GetGlyph (Hii, UnicodeWeight, &StringIndex, (UINT8 **) &Glyph, &GlyphWidth, &GlyphStatus);
662 if (EFI_ERROR (Status)) {
663 goto Error;
664 }
665
666 if (Foreground == NULL || Background == NULL) {
667 Status = Hii->GlyphToBlt (
668 Hii,
669 (UINT8 *) Glyph,
670 mEfiColors[Sto->Mode->Attribute & 0x0f],
671 mEfiColors[Sto->Mode->Attribute >> 4],
672 StrLen (Buffer),
673 GlyphWidth,
674 GLYPH_HEIGHT,
675 &LineBuffer[Index * GLYPH_WIDTH]
676 );
677 } else {
678 Status = Hii->GlyphToBlt (
679 Hii,
680 (UINT8 *) Glyph,
681 *Foreground,
682 *Background,
683 StrLen (Buffer),
684 GlyphWidth,
685 GLYPH_HEIGHT,
686 &LineBuffer[Index * GLYPH_WIDTH]
687 );
688 }
689 }
690
691 //
692 // Blt a character to the screen
693 //
694 Status = UgaDraw->Blt (
695 UgaDraw,
696 LineBuffer,
697 EfiUgaBltBufferToVideo,
698 0,
699 0,
700 X,
701 Y,
702 GLYPH_WIDTH * StrLen (Buffer),
703 GLYPH_HEIGHT,
704 GLYPH_WIDTH * StrLen (Buffer) * sizeof (EFI_UGA_PIXEL)
705 );
706
707 Error:
708 gBS->FreePool (LineBuffer);
709 gBS->FreePool (Buffer);
710 return Status;
711 }
712
713
714 UINTN
715 PrintXY (
716 IN UINTN X,
717 IN UINTN Y,
718 IN EFI_UGA_PIXEL *ForeGround, OPTIONAL
719 IN EFI_UGA_PIXEL *BackGround, OPTIONAL
720 IN CHAR16 *Fmt,
721 ...
722 )
723 /*++
724
725 Routine Description:
726
727 Prints a formatted unicode string to the default console
728
729 Arguments:
730
731 X - X coordinate to start printing
732
733 Y - Y coordinate to start printing
734
735 ForeGround - Foreground color
736
737 BackGround - Background color
738
739 Fmt - Format string
740
741 ... - Print arguments
742
743 Returns:
744
745 Length of string printed to the console
746
747 --*/
748 {
749 EFI_HANDLE Handle;
750 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
751 EFI_SIMPLE_TEXT_OUT_PROTOCOL *Sto;
752 EFI_STATUS Status;
753 VA_LIST Args;
754
755 VA_START (Args, Fmt);
756
757 Handle = gST->ConsoleOutHandle;
758
759 Status = gBS->HandleProtocol (
760 Handle,
761 &gEfiUgaDrawProtocolGuid,
762 (VOID **) &UgaDraw
763 );
764
765 if (EFI_ERROR (Status)) {
766 return Status;
767 }
768
769 Status = gBS->HandleProtocol (
770 Handle,
771 &gEfiSimpleTextOutProtocolGuid,
772 (VOID **) &Sto
773 );
774
775 if (EFI_ERROR (Status)) {
776 return Status;
777 }
778
779 return _IPrint (UgaDraw, Sto, X, Y, ForeGround, BackGround, Fmt, Args);
780 }