Merger trackers #7807 and #8372.
[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 #include <Library/DebugLib.h>
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 GOP/UGA blt buffer. If a NULL Blt buffer
137 is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt
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 GopBlt - Buffer containing GOP version of BmpImage.
147
148 GopBltSize - Size of GopBlt in bytes.
149
150 PixelHeight - Height of GopBlt/BmpImage in pixels
151
152 PixelWidth - Width of GopBlt/BmpImage in pixels
153
154
155 Returns:
156
157 EFI_SUCCESS - GopBlt and GopBltSize are returned.
158 EFI_UNSUPPORTED - BmpImage is not a valid *.BMP image
159 EFI_BUFFER_TOO_SMALL - The passed in GopBlt buffer is not big enough.
160 GopBltSize 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 GOP/UGA based Simple Text Out consoles. The GOP/UGA
579 Simple Text Out screens will now be synced up with all non GOP/UGA output devices
580
581 Arguments:
582
583 NONE
584
585 Returns:
586
587 EFI_SUCCESS - GOP/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 BufferLen;
683 UINTN LineBufferLen;
684 UINTN BufferGlyphWidth;
685
686 GlyphStatus = 0;
687
688 //
689 // For now, allocate an arbitrarily long buffer
690 //
691 Buffer = AllocateZeroPool (0x10000);
692 if (Buffer == NULL) {
693 return EFI_OUT_OF_RESOURCES;
694 }
695
696 if (GraphicsOutput != NULL) {
697 HorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
698 VerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;
699 } else {
700 //
701 // Get the current mode information from the UGA Draw Protocol
702 //
703 UgaDraw->GetMode (UgaDraw, &HorizontalResolution, &VerticalResolution, &ColorDepth, &RefreshRate);
704 }
705 ASSERT ((HorizontalResolution != 0) && (VerticalResolution !=0));
706
707 LineBufferLen = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * HorizontalResolution * GLYPH_HEIGHT;
708 LineBuffer = AllocatePool (LineBufferLen);
709 if (LineBuffer == NULL) {
710 gBS->FreePool (Buffer);
711 return EFI_OUT_OF_RESOURCES;
712 }
713
714 Status = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, (VOID **) &Hii);
715 if (EFI_ERROR (Status)) {
716 goto Error;
717 }
718
719 UnicodeVSPrint (Buffer, 0x10000, fmt, args);
720
721 UnicodeWeight = (CHAR16 *) Buffer;
722
723 for (Index = 0; UnicodeWeight[Index] != 0; Index++) {
724 if (UnicodeWeight[Index] == CHAR_BACKSPACE ||
725 UnicodeWeight[Index] == CHAR_LINEFEED ||
726 UnicodeWeight[Index] == CHAR_CARRIAGE_RETURN) {
727 UnicodeWeight[Index] = 0;
728 }
729 }
730
731 BufferLen = StrLen (Buffer);
732
733 if (GLYPH_WIDTH * GLYPH_HEIGHT * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * BufferLen > LineBufferLen) {
734 Status = EFI_INVALID_PARAMETER;
735 goto Error;
736 }
737
738 for (Index = 0; Index < BufferLen; Index++) {
739 StringIndex = (UINT16) Index;
740 Status = Hii->GetGlyph (Hii, UnicodeWeight, &StringIndex, (UINT8 **) &Glyph, &GlyphWidth, &GlyphStatus);
741 if (EFI_ERROR (Status)) {
742 goto Error;
743 }
744
745 if (Foreground == NULL || Background == NULL) {
746 Status = Hii->GlyphToBlt (
747 Hii,
748 (UINT8 *) Glyph,
749 mEfiColors[Sto->Mode->Attribute & 0x0f],
750 mEfiColors[Sto->Mode->Attribute >> 4],
751 BufferLen,
752 GlyphWidth,
753 GLYPH_HEIGHT,
754 &LineBuffer[Index * GLYPH_WIDTH]
755 );
756 } else {
757 Status = Hii->GlyphToBlt (
758 Hii,
759 (UINT8 *) Glyph,
760 *Foreground,
761 *Background,
762 BufferLen,
763 GlyphWidth,
764 GLYPH_HEIGHT,
765 &LineBuffer[Index * GLYPH_WIDTH]
766 );
767 }
768 }
769
770 //
771 // Blt a character to the screen
772 //
773 BufferGlyphWidth = GLYPH_WIDTH * BufferLen;
774 if (GraphicsOutput != NULL) {
775 Status = GraphicsOutput->Blt (
776 GraphicsOutput,
777 LineBuffer,
778 EfiBltBufferToVideo,
779 0,
780 0,
781 X,
782 Y,
783 BufferGlyphWidth,
784 GLYPH_HEIGHT,
785 BufferGlyphWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
786 );
787 } else {
788 Status = UgaDraw->Blt (
789 UgaDraw,
790 (EFI_UGA_PIXEL *) (UINTN) LineBuffer,
791 EfiUgaBltBufferToVideo,
792 0,
793 0,
794 X,
795 Y,
796 BufferGlyphWidth,
797 GLYPH_HEIGHT,
798 BufferGlyphWidth * sizeof (EFI_UGA_PIXEL)
799 );
800 }
801
802 Error:
803 gBS->FreePool (LineBuffer);
804 gBS->FreePool (Buffer);
805 return Status;
806 }
807
808
809 UINTN
810 PrintXY (
811 IN UINTN X,
812 IN UINTN Y,
813 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ForeGround, OPTIONAL
814 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BackGround, OPTIONAL
815 IN CHAR16 *Fmt,
816 ...
817 )
818 /*++
819
820 Routine Description:
821
822 Prints a formatted unicode string to the default console
823
824 Arguments:
825
826 X - X coordinate to start printing
827
828 Y - Y coordinate to start printing
829
830 ForeGround - Foreground color
831
832 BackGround - Background color
833
834 Fmt - Format string
835
836 ... - Print arguments
837
838 Returns:
839
840 Length of string printed to the console
841
842 --*/
843 {
844 EFI_HANDLE Handle;
845
846 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
847 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
848 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Sto;
849 EFI_STATUS Status;
850 VA_LIST Args;
851
852 VA_START (Args, Fmt);
853
854 UgaDraw = NULL;
855
856 Handle = gST->ConsoleOutHandle;
857
858 Status = gBS->HandleProtocol (
859 Handle,
860 &gEfiGraphicsOutputProtocolGuid,
861 (VOID **) &GraphicsOutput
862 );
863
864 if (EFI_ERROR (Status)) {
865 GraphicsOutput = NULL;
866
867 Status = gBS->HandleProtocol (
868 Handle,
869 &gEfiUgaDrawProtocolGuid,
870 (VOID **) &UgaDraw
871 );
872
873 if (EFI_ERROR (Status)) {
874 return Status;
875 }
876 }
877
878 Status = gBS->HandleProtocol (
879 Handle,
880 &gEfiSimpleTextOutProtocolGuid,
881 (VOID **) &Sto
882 );
883
884 if (EFI_ERROR (Status)) {
885 return Status;
886 }
887
888 return _IPrint (GraphicsOutput, UgaDraw, Sto, X, Y, ForeGround, BackGround, Fmt, Args);
889 }