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