2 This is the main routine for initializing the Graphics Console support routines.
4 Copyright (c) 2006 - 2008 Intel Corporation. <BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "GraphicsConsole.h"
18 // Graphics Console Device Private Data template
20 GRAPHICS_CONSOLE_DEV mGraphicsConsoleDevTemplate
= {
21 GRAPHICS_CONSOLE_DEV_SIGNATURE
,
22 (EFI_GRAPHICS_OUTPUT_PROTOCOL
*) NULL
,
23 (EFI_UGA_DRAW_PROTOCOL
*) NULL
,
25 GraphicsConsoleConOutReset
,
26 GraphicsConsoleConOutOutputString
,
27 GraphicsConsoleConOutTestString
,
28 GraphicsConsoleConOutQueryMode
,
29 GraphicsConsoleConOutSetMode
,
30 GraphicsConsoleConOutSetAttribute
,
31 GraphicsConsoleConOutClearScreen
,
32 GraphicsConsoleConOutSetCursorPosition
,
33 GraphicsConsoleConOutEnableCursor
,
34 (EFI_SIMPLE_TEXT_OUTPUT_MODE
*) NULL
39 EFI_TEXT_ATTR(EFI_LIGHTGRAY
, EFI_BLACK
),
45 { 80, 25, 0, 0, 0, 0 }, // Mode 0
46 { 80, 50, 0, 0, 0, 0 }, // Mode 1
47 { 100,31, 0, 0, 0, 0 }, // Mode 2
48 { 0, 0, 0, 0, 0, 0 } // Mode 3
50 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) NULL
,
54 EFI_HII_DATABASE_PROTOCOL
*mHiiDatabase
;
55 EFI_HII_FONT_PROTOCOL
*mHiiFont
;
56 BOOLEAN mFirstAccessFlag
= TRUE
;
58 EFI_GUID mFontPackageListGuid
= {0xf5f219d3, 0x7006, 0x4648, {0xac, 0x8d, 0xd6, 0x1d, 0xfb, 0x7b, 0xc6, 0xad}};
60 CHAR16 mCrLfString
[3] = { CHAR_CARRIAGE_RETURN
, CHAR_LINEFEED
, CHAR_NULL
};
62 EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors
[16] = {
66 {0x00, 0x00, 0x00, 0x00}, // BLACK
67 {0x98, 0x00, 0x00, 0x00}, // LIGHTBLUE
68 {0x00, 0x98, 0x00, 0x00}, // LIGHGREEN
69 {0x98, 0x98, 0x00, 0x00}, // LIGHCYAN
70 {0x00, 0x00, 0x98, 0x00}, // LIGHRED
71 {0x98, 0x00, 0x98, 0x00}, // MAGENTA
72 {0x00, 0x98, 0x98, 0x00}, // BROWN
73 {0x98, 0x98, 0x98, 0x00}, // LIGHTGRAY
74 {0x30, 0x30, 0x30, 0x00}, // DARKGRAY - BRIGHT BLACK
75 {0xff, 0x00, 0x00, 0x00}, // BLUE
76 {0x00, 0xff, 0x00, 0x00}, // LIME
77 {0xff, 0xff, 0x00, 0x00}, // CYAN
78 {0x00, 0x00, 0xff, 0x00}, // RED
79 {0xff, 0x00, 0xff, 0x00}, // FUCHSIA
80 {0x00, 0xff, 0xff, 0x00}, // YELLOW
81 {0xff, 0xff, 0xff, 0x00} // WHITE
84 EFI_NARROW_GLYPH mCursorGlyph
= {
87 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF }
90 CHAR16 SpaceStr
[] = { NARROW_CHAR
, ' ', 0 };
92 EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding
= {
93 GraphicsConsoleControllerDriverSupported
,
94 GraphicsConsoleControllerDriverStart
,
95 GraphicsConsoleControllerDriverStop
,
102 Test to see if Graphics Console could be supported on the Controller.
104 Graphics Console could be supported if Graphics Output Protocol or UGA Draw
105 Protocol exists on the Controller. (UGA Draw Protocol could be skipped
106 if PcdUgaConsumeSupport is set to FALSE.)
108 @param This Protocol instance pointer.
109 @param Controller Handle of device to test.
110 @param RemainingDevicePath Optional parameter use to pick a specific child
113 @retval EFI_SUCCESS This driver supports this device.
114 @retval other This driver does not support this device.
119 GraphicsConsoleControllerDriverSupported (
120 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
121 IN EFI_HANDLE Controller
,
122 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
126 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
127 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
128 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
130 GraphicsOutput
= NULL
;
133 // Open the IO Abstraction(s) needed to perform the supported test
135 Status
= gBS
->OpenProtocol (
137 &gEfiGraphicsOutputProtocolGuid
,
138 (VOID
**) &GraphicsOutput
,
139 This
->DriverBindingHandle
,
141 EFI_OPEN_PROTOCOL_BY_DRIVER
144 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
146 // Open Graphics Output Protocol failed, try to open UGA Draw Protocol
148 Status
= gBS
->OpenProtocol (
150 &gEfiUgaDrawProtocolGuid
,
152 This
->DriverBindingHandle
,
154 EFI_OPEN_PROTOCOL_BY_DRIVER
157 if (EFI_ERROR (Status
)) {
162 // We need to ensure that we do not layer on top of a virtual handle.
163 // We need to ensure that the handles produced by the conspliter do not
166 Status
= gBS
->OpenProtocol (
168 &gEfiDevicePathProtocolGuid
,
169 (VOID
**) &DevicePath
,
170 This
->DriverBindingHandle
,
172 EFI_OPEN_PROTOCOL_BY_DRIVER
174 if (!EFI_ERROR (Status
)) {
177 &gEfiDevicePathProtocolGuid
,
178 This
->DriverBindingHandle
,
186 // Does Hii Exist? If not, we aren't ready to run
188 Status
= EfiLocateHiiProtocol ();
191 // Close the I/O Abstraction(s) used to perform the supported test
194 if (GraphicsOutput
!= NULL
) {
197 &gEfiGraphicsOutputProtocolGuid
,
198 This
->DriverBindingHandle
,
201 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
204 &gEfiUgaDrawProtocolGuid
,
205 This
->DriverBindingHandle
,
214 Start this driver on Controller by opening Graphics Output protocol or
215 UGA Draw protocol, and installing Simple Text Out protocol on Controller.
216 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)
218 @param This Protocol instance pointer.
219 @param Controller Handle of device to bind driver to
220 @param RemainingDevicePath Optional parameter use to pick a specific child
223 @retval EFI_SUCCESS This driver is added to Controller.
224 @retval other This driver does not support this device.
229 GraphicsConsoleControllerDriverStart (
230 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
231 IN EFI_HANDLE Controller
,
232 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
236 GRAPHICS_CONSOLE_DEV
*Private
;
237 UINT32 NarrowFontSize
;
238 UINT32 HorizontalResolution
;
239 UINT32 VerticalResolution
;
246 EFI_HII_SIMPLE_FONT_PACKAGE_HDR
*SimplifiedFont
;
247 UINT32 PackageLength
;
248 EFI_HII_PACKAGE_LIST_HEADER
*PackageList
;
251 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
*Mode
;
255 // Initialize the Graphics Console device instance
257 Private
= AllocateCopyPool (
258 sizeof (GRAPHICS_CONSOLE_DEV
),
259 &mGraphicsConsoleDevTemplate
261 if (Private
== NULL
) {
262 return EFI_OUT_OF_RESOURCES
;
265 Private
->SimpleTextOutput
.Mode
= &(Private
->SimpleTextOutputMode
);
267 Status
= gBS
->OpenProtocol (
269 &gEfiGraphicsOutputProtocolGuid
,
270 (VOID
**) &Private
->GraphicsOutput
,
271 This
->DriverBindingHandle
,
273 EFI_OPEN_PROTOCOL_BY_DRIVER
276 if (EFI_ERROR(Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
277 Status
= gBS
->OpenProtocol (
279 &gEfiUgaDrawProtocolGuid
,
280 (VOID
**) &Private
->UgaDraw
,
281 This
->DriverBindingHandle
,
283 EFI_OPEN_PROTOCOL_BY_DRIVER
287 if (EFI_ERROR (Status
)) {
291 NarrowFontSize
= mNarrowFontSize
;
293 if (mFirstAccessFlag
) {
295 // Add 4 bytes to the header for entire length for HiiLibPreparePackageList use only.
296 // Looks ugly. Might be updated when font tool is ready.
298 // +--------------------------------+ <-- Package
300 // | PackageLength(4 bytes) |
302 // |--------------------------------| <-- SimplifiedFont
304 // |EFI_HII_SIMPLE_FONT_PACKAGE_HDR |
306 // |--------------------------------| <-- Location
308 // | gUsStdNarrowGlyphData |
310 // +--------------------------------+
312 PackageLength
= sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR
) + NarrowFontSize
+ 4;
313 Package
= AllocateZeroPool (PackageLength
);
314 if (Package
== NULL
) {
315 return EFI_OUT_OF_RESOURCES
;
317 WriteUnaligned32((UINT32
*) Package
,PackageLength
);
318 SimplifiedFont
= (EFI_HII_SIMPLE_FONT_PACKAGE_HDR
*) (Package
+ 4);
319 SimplifiedFont
->Header
.Length
= (UINT32
) (PackageLength
- 4);
320 SimplifiedFont
->Header
.Type
= EFI_HII_PACKAGE_SIMPLE_FONTS
;
321 SimplifiedFont
->NumberOfNarrowGlyphs
= (UINT16
) (NarrowFontSize
/ sizeof (EFI_NARROW_GLYPH
));
323 Location
= (UINT8
*) (&SimplifiedFont
->NumberOfWideGlyphs
+ 1);
324 CopyMem (Location
, gUsStdNarrowGlyphData
, NarrowFontSize
);
327 // Add this simplified font package to a package list then install it.
329 PackageList
= HiiLibPreparePackageList (1, &mFontPackageListGuid
, Package
);
330 Status
= mHiiDatabase
->NewPackageList (mHiiDatabase
, PackageList
, NULL
, &(Private
->HiiHandle
));
331 ASSERT_EFI_ERROR (Status
);
332 FreePool (PackageList
);
335 mFirstAccessFlag
= FALSE
;
338 // If the current mode information can not be retrieved, then attempt to set the default mode
339 // of 800x600, 32 bit color, 60 Hz refresh.
341 HorizontalResolution
= 800;
342 VerticalResolution
= 600;
344 if (Private
->GraphicsOutput
!= NULL
) {
346 // The console is build on top of Graphics Output Protocol, find the mode number
347 // for the user-defined mode; if there are multiple video devices,
348 // graphic console driver will set all the video devices to the same mode.
350 Status
= CheckModeSupported (
351 Private
->GraphicsOutput
,
352 CURRENT_HORIZONTAL_RESOLUTION
,
353 CURRENT_VERTICAL_RESOLUTION
,
356 if (!EFI_ERROR(Status
)) {
358 // Update default mode to current mode
360 HorizontalResolution
= CURRENT_HORIZONTAL_RESOLUTION
;
361 VerticalResolution
= CURRENT_VERTICAL_RESOLUTION
;
364 // if not supporting current mode, try 800x600 which is required by UEFI/EFI spec
366 Status
= CheckModeSupported (
367 Private
->GraphicsOutput
,
374 Mode
= Private
->GraphicsOutput
->Mode
;
376 if (EFI_ERROR (Status
) || (Mode
->MaxMode
!= 0)) {
378 // Set default mode failed or device don't support default mode, then get the current mode information
380 HorizontalResolution
= Mode
->Info
->HorizontalResolution
;
381 VerticalResolution
= Mode
->Info
->VerticalResolution
;
382 ModeNumber
= Mode
->Mode
;
384 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
386 // At first try to set user-defined resolution
390 Status
= Private
->UgaDraw
->SetMode (
392 CURRENT_HORIZONTAL_RESOLUTION
,
393 CURRENT_VERTICAL_RESOLUTION
,
397 if (!EFI_ERROR (Status
)) {
398 HorizontalResolution
= CURRENT_HORIZONTAL_RESOLUTION
;
399 VerticalResolution
= CURRENT_VERTICAL_RESOLUTION
;
400 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
402 // Try to set 800*600 which is required by UEFI/EFI spec
404 Status
= Private
->UgaDraw
->SetMode (
406 HorizontalResolution
,
411 if (EFI_ERROR (Status
)) {
412 Status
= Private
->UgaDraw
->GetMode (
414 &HorizontalResolution
,
419 if (EFI_ERROR (Status
)) {
424 Status
= EFI_UNSUPPORTED
;
430 // Compute the maximum number of text Rows and Columns that this current graphics mode can support
432 Columns
= HorizontalResolution
/ EFI_GLYPH_WIDTH
;
433 Rows
= VerticalResolution
/ EFI_GLYPH_HEIGHT
;
436 // See if the mode is too small to support the required 80x25 text mode
438 if (Columns
< 80 || Rows
< 25) {
442 // Add Mode #0 that must be 80x25
445 Private
->ModeData
[MaxMode
].GopWidth
= HorizontalResolution
;
446 Private
->ModeData
[MaxMode
].GopHeight
= VerticalResolution
;
447 Private
->ModeData
[MaxMode
].GopModeNumber
= ModeNumber
;
448 Private
->ModeData
[MaxMode
].DeltaX
= (HorizontalResolution
- (80 * EFI_GLYPH_WIDTH
)) >> 1;
449 Private
->ModeData
[MaxMode
].DeltaY
= (VerticalResolution
- (25 * EFI_GLYPH_HEIGHT
)) >> 1;
453 // If it is possible to support Mode #1 - 80x50, than add it as an active mode
456 Private
->ModeData
[MaxMode
].GopWidth
= HorizontalResolution
;
457 Private
->ModeData
[MaxMode
].GopHeight
= VerticalResolution
;
458 Private
->ModeData
[MaxMode
].GopModeNumber
= ModeNumber
;
459 Private
->ModeData
[MaxMode
].DeltaX
= (HorizontalResolution
- (80 * EFI_GLYPH_WIDTH
)) >> 1;
460 Private
->ModeData
[MaxMode
].DeltaY
= (VerticalResolution
- (50 * EFI_GLYPH_HEIGHT
)) >> 1;
465 // If it is not to support Mode #1 - 80x50, then skip it
468 Private
->ModeData
[MaxMode
].Columns
= 0;
469 Private
->ModeData
[MaxMode
].Rows
= 0;
470 Private
->ModeData
[MaxMode
].GopWidth
= HorizontalResolution
;
471 Private
->ModeData
[MaxMode
].GopHeight
= VerticalResolution
;
472 Private
->ModeData
[MaxMode
].GopModeNumber
= ModeNumber
;
473 Private
->ModeData
[MaxMode
].DeltaX
= 0;
474 Private
->ModeData
[MaxMode
].DeltaY
= 0;
479 // Add Mode #2 that must be 100x31 (graphic mode >= 800x600)
481 if (Columns
>= 100 && Rows
>= 31) {
482 Private
->ModeData
[MaxMode
].GopWidth
= HorizontalResolution
;
483 Private
->ModeData
[MaxMode
].GopHeight
= VerticalResolution
;
484 Private
->ModeData
[MaxMode
].GopModeNumber
= ModeNumber
;
485 Private
->ModeData
[MaxMode
].DeltaX
= (HorizontalResolution
- (100 * EFI_GLYPH_WIDTH
)) >> 1;
486 Private
->ModeData
[MaxMode
].DeltaY
= (VerticalResolution
- (31 * EFI_GLYPH_HEIGHT
)) >> 1;
491 // Add Mode #3 that uses the entire display for user-defined mode
493 if (HorizontalResolution
> 800 && VerticalResolution
> 600) {
494 Private
->ModeData
[MaxMode
].Columns
= HorizontalResolution
/EFI_GLYPH_WIDTH
;
495 Private
->ModeData
[MaxMode
].Rows
= VerticalResolution
/EFI_GLYPH_HEIGHT
;
496 Private
->ModeData
[MaxMode
].GopWidth
= HorizontalResolution
;
497 Private
->ModeData
[MaxMode
].GopHeight
= VerticalResolution
;
498 Private
->ModeData
[MaxMode
].GopModeNumber
= ModeNumber
;
499 Private
->ModeData
[MaxMode
].DeltaX
= (HorizontalResolution
% EFI_GLYPH_WIDTH
) >> 1;
500 Private
->ModeData
[MaxMode
].DeltaY
= (VerticalResolution
% EFI_GLYPH_HEIGHT
) >> 1;
505 // Update the maximum number of modes
507 Private
->SimpleTextOutputMode
.MaxMode
= (INT32
) MaxMode
;
510 // Determine the number of text modes that this protocol can support
512 Status
= GraphicsConsoleConOutSetMode (&Private
->SimpleTextOutput
, 0);
513 if (EFI_ERROR (Status
)) {
518 GraphicsConsoleConOutOutputString (&Private
->SimpleTextOutput
, (CHAR16
*)L
"Graphics Console Started\n\r");
522 // Install protocol interfaces for the Graphics Console device.
524 Status
= gBS
->InstallMultipleProtocolInterfaces (
526 &gEfiSimpleTextOutProtocolGuid
,
527 &Private
->SimpleTextOutput
,
532 if (EFI_ERROR (Status
)) {
534 // Close the GOP and UGA Draw Protocol
536 if (Private
->GraphicsOutput
!= NULL
) {
539 &gEfiGraphicsOutputProtocolGuid
,
540 This
->DriverBindingHandle
,
543 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
546 &gEfiUgaDrawProtocolGuid
,
547 This
->DriverBindingHandle
,
555 if (Private
!= NULL
) {
556 if (Private
->LineBuffer
!= NULL
) {
557 FreePool (Private
->LineBuffer
);
567 Stop this driver on Controller by removing Simple Text Out protocol
568 and closing the Graphics Output Protocol or UGA Draw protocol on Controller.
569 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)
572 @param This Protocol instance pointer.
573 @param Controller Handle of device to stop driver on
574 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
575 children is zero stop the entire bus driver.
576 @param ChildHandleBuffer List of Child Handles to Stop.
578 @retval EFI_SUCCESS This driver is removed Controller.
579 @retval EFI_NOT_STARTED Simple Text Out protocol could not be found the
581 @retval other This driver was not removed from this device.
586 GraphicsConsoleControllerDriverStop (
587 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
588 IN EFI_HANDLE Controller
,
589 IN UINTN NumberOfChildren
,
590 IN EFI_HANDLE
*ChildHandleBuffer
594 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
595 GRAPHICS_CONSOLE_DEV
*Private
;
597 Status
= gBS
->OpenProtocol (
599 &gEfiSimpleTextOutProtocolGuid
,
600 (VOID
**) &SimpleTextOutput
,
601 This
->DriverBindingHandle
,
603 EFI_OPEN_PROTOCOL_GET_PROTOCOL
605 if (EFI_ERROR (Status
)) {
606 return EFI_NOT_STARTED
;
609 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
611 Status
= gBS
->UninstallProtocolInterface (
613 &gEfiSimpleTextOutProtocolGuid
,
614 &Private
->SimpleTextOutput
617 if (!EFI_ERROR (Status
)) {
619 // Close the GOP or UGA IO Protocol
621 if (Private
->GraphicsOutput
!= NULL
) {
624 &gEfiGraphicsOutputProtocolGuid
,
625 This
->DriverBindingHandle
,
628 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
631 &gEfiUgaDrawProtocolGuid
,
632 This
->DriverBindingHandle
,
638 // Remove the font pack
640 if (Private
->HiiHandle
!= NULL
) {
641 HiiLibRemovePackages (Private
->HiiHandle
);
642 mFirstAccessFlag
= TRUE
;
646 // Free our instance data
648 if (Private
!= NULL
) {
649 FreePool (Private
->LineBuffer
);
658 Check if the current specific mode supported the user defined resolution
659 for the Graphics Console device based on Graphics Output Protocol.
661 If yes, set the graphic devcice's current mode to this specific mode.
663 @param GraphicsOutput Graphics Output Protocol instance pointer.
664 @param HorizontalResolution User defined horizontal resolution
665 @param VerticalResolution User defined vertical resolution.
666 @param CurrentModeNumber Current specific mode to be check.
668 @retval EFI_SUCCESS The mode is supported.
669 @retval EFI_UNSUPPORTED The specific mode is out of range of graphics
671 @retval other The specific mode does not support user defined
672 resolution or failed to set the current mode to the
673 specific mode on graphics device.
678 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
679 IN UINT32 HorizontalResolution
,
680 IN UINT32 VerticalResolution
,
681 OUT UINT32
*CurrentModeNumber
687 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
690 Status
= EFI_SUCCESS
;
691 MaxMode
= GraphicsOutput
->Mode
->MaxMode
;
693 for (ModeNumber
= 0; ModeNumber
< MaxMode
; ModeNumber
++) {
694 Status
= GraphicsOutput
->QueryMode (
700 if (!EFI_ERROR (Status
)) {
701 if ((Info
->HorizontalResolution
== HorizontalResolution
) &&
702 (Info
->VerticalResolution
== VerticalResolution
)) {
703 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeNumber
);
704 if (!EFI_ERROR (Status
)) {
713 if (ModeNumber
== GraphicsOutput
->Mode
->MaxMode
) {
714 Status
= EFI_UNSUPPORTED
;
717 *CurrentModeNumber
= ModeNumber
;
723 Locate HII Database protocol and HII Font protocol.
725 @retval EFI_SUCCESS HII Database protocol and HII Font protocol
726 are located successfully.
727 @return other Failed to locate HII Database protocol or
732 EfiLocateHiiProtocol (
741 // There should only be one - so buffer size is this
743 Size
= sizeof (EFI_HANDLE
);
745 Status
= gBS
->LocateHandle (
747 &gEfiHiiDatabaseProtocolGuid
,
753 if (EFI_ERROR (Status
)) {
757 Status
= gBS
->HandleProtocol (
759 &gEfiHiiDatabaseProtocolGuid
,
760 (VOID
**) &mHiiDatabase
763 if (EFI_ERROR (Status
)) {
767 Status
= gBS
->HandleProtocol (
769 &gEfiHiiFontProtocolGuid
,
776 // Body of the STO functions
780 Reset the text output device hardware and optionally run diagnostics.
782 Implements SIMPLE_TEXT_OUTPUT.Reset().
783 If ExtendeVerification is TRUE, then perform dependent Graphics Console
784 device reset, and set display mode to mode 0.
785 If ExtendedVerification is FALSE, only set display mode to mode 0.
787 @param This Protocol instance pointer.
788 @param ExtendedVerification Indicates that the driver may perform a more
789 exhaustive verification operation of the device
792 @retval EFI_SUCCESS The text output device was reset.
793 @retval EFI_DEVICE_ERROR The text output device is not functioning correctly and
799 GraphicsConsoleConOutReset (
800 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
801 IN BOOLEAN ExtendedVerification
804 This
->SetAttribute (This
, EFI_TEXT_ATTR (This
->Mode
->Attribute
& 0x0F, EFI_BACKGROUND_BLACK
));
805 return This
->SetMode (This
, 0);
810 Write a Unicode string to the output device.
812 Implements SIMPLE_TEXT_OUTPUT.OutputString().
813 The Unicode string will be converted to Glyphs and will be
814 sent to the Graphics Console.
816 @param This Protocol instance pointer.
817 @param WString The NULL-terminated Unicode string to be displayed
818 on the output device(s). All output devices must
819 also support the Unicode drawing defined in this file.
821 @retval EFI_SUCCESS The string was output to the device.
822 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output
824 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
826 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
827 characters in the Unicode string could not be
828 rendered and were skipped.
833 GraphicsConsoleConOutOutputString (
834 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
838 GRAPHICS_CONSOLE_DEV
*Private
;
839 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
840 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
849 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
850 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
855 INT32 OriginAttribute
;
858 Status
= EFI_SUCCESS
;
860 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
864 Mode
= This
->Mode
->Mode
;
865 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
866 GraphicsOutput
= Private
->GraphicsOutput
;
867 UgaDraw
= Private
->UgaDraw
;
869 MaxColumn
= Private
->ModeData
[Mode
].Columns
;
870 MaxRow
= Private
->ModeData
[Mode
].Rows
;
871 DeltaX
= Private
->ModeData
[Mode
].DeltaX
;
872 DeltaY
= Private
->ModeData
[Mode
].DeltaY
;
873 Width
= MaxColumn
* EFI_GLYPH_WIDTH
;
874 Height
= (MaxRow
- 1) * EFI_GLYPH_HEIGHT
;
875 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
878 // The Attributes won't change when during the time OutputString is called
880 GetTextColors (This
, &Foreground
, &Background
);
889 OriginAttribute
= This
->Mode
->Attribute
;
891 while (*WString
!= L
'\0') {
893 if (*WString
== CHAR_BACKSPACE
) {
895 // If the cursor is at the left edge of the display, then move the cursor
898 if (This
->Mode
->CursorColumn
== 0 && This
->Mode
->CursorRow
> 0) {
899 This
->Mode
->CursorRow
--;
900 This
->Mode
->CursorColumn
= (INT32
) (MaxColumn
- 1);
901 This
->OutputString (This
, SpaceStr
);
903 This
->Mode
->CursorRow
--;
904 This
->Mode
->CursorColumn
= (INT32
) (MaxColumn
- 1);
905 } else if (This
->Mode
->CursorColumn
> 0) {
907 // If the cursor is not at the left edge of the display, then move the cursor
910 This
->Mode
->CursorColumn
--;
911 This
->OutputString (This
, SpaceStr
);
913 This
->Mode
->CursorColumn
--;
918 } else if (*WString
== CHAR_LINEFEED
) {
920 // If the cursor is at the bottom of the display, then scroll the display one
921 // row, and do not update the cursor position. Otherwise, move the cursor
924 if (This
->Mode
->CursorRow
== (INT32
) (MaxRow
- 1)) {
925 if (GraphicsOutput
!= NULL
) {
927 // Scroll Screen Up One Row
929 GraphicsOutput
->Blt (
934 DeltaY
+ EFI_GLYPH_HEIGHT
,
943 // Print Blank Line at last line
945 GraphicsOutput
->Blt (
957 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
959 // Scroll Screen Up One Row
966 DeltaY
+ EFI_GLYPH_HEIGHT
,
975 // Print Blank Line at last line
979 (EFI_UGA_PIXEL
*) (UINTN
) &Background
,
991 This
->Mode
->CursorRow
++;
996 } else if (*WString
== CHAR_CARRIAGE_RETURN
) {
998 // Move the cursor to the beginning of the current row.
1000 This
->Mode
->CursorColumn
= 0;
1003 } else if (*WString
== WIDE_CHAR
) {
1005 This
->Mode
->Attribute
|= EFI_WIDE_ATTRIBUTE
;
1008 } else if (*WString
== NARROW_CHAR
) {
1010 This
->Mode
->Attribute
&= (~ (UINT32
) EFI_WIDE_ATTRIBUTE
);
1015 // Print the character at the current cursor position and move the cursor
1016 // right one column. If this moves the cursor past the right edge of the
1017 // display, then the line should wrap to the beginning of the next line. This
1018 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the
1019 // bottom of the display, and the line wraps, then the display will be scrolled
1021 // If wide char is going to be displayed, need to display one character at a time
1022 // Or, need to know the display length of a certain string.
1024 // Index is used to determine how many character width units (wide = 2, narrow = 1)
1025 // Count is used to determine how many characters are used regardless of their attributes
1027 for (Count
= 0, Index
= 0; (This
->Mode
->CursorColumn
+ Index
) < MaxColumn
; Count
++, Index
++) {
1028 if (WString
[Count
] == CHAR_NULL
||
1029 WString
[Count
] == CHAR_BACKSPACE
||
1030 WString
[Count
] == CHAR_LINEFEED
||
1031 WString
[Count
] == CHAR_CARRIAGE_RETURN
||
1032 WString
[Count
] == WIDE_CHAR
||
1033 WString
[Count
] == NARROW_CHAR
) {
1037 // Is the wide attribute on?
1039 if ((This
->Mode
->Attribute
& EFI_WIDE_ATTRIBUTE
) != 0) {
1041 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop
1045 // This is the end-case where if we are at column 79 and about to print a wide character
1046 // We should prevent this from happening because we will wrap inappropriately. We should
1047 // not print this character until the next line.
1049 if ((This
->Mode
->CursorColumn
+ Index
+ 1) > MaxColumn
) {
1056 Status
= DrawUnicodeWeightAtCursorN (This
, WString
, Count
);
1057 if (EFI_ERROR (Status
)) {
1061 // At the end of line, output carriage return and line feed
1064 This
->Mode
->CursorColumn
+= (INT32
) Index
;
1065 if (This
->Mode
->CursorColumn
> (INT32
) MaxColumn
) {
1066 This
->Mode
->CursorColumn
-= 2;
1067 This
->OutputString (This
, SpaceStr
);
1070 if (This
->Mode
->CursorColumn
>= (INT32
) MaxColumn
) {
1072 This
->OutputString (This
, mCrLfString
);
1078 This
->Mode
->Attribute
= OriginAttribute
;
1083 Status
= EFI_WARN_UNKNOWN_GLYPH
;
1086 gBS
->RestoreTPL (OldTpl
);
1092 Verifies that all characters in a Unicode string can be output to the
1095 Implements SIMPLE_TEXT_OUTPUT.TestString().
1096 If one of the characters in the *Wstring is neither valid valid Unicode
1097 drawing characters, not ASCII code, then this function will return
1100 @param This Protocol instance pointer.
1101 @param WString The NULL-terminated Unicode string to be examined for the output
1104 @retval EFI_SUCCESS The device(s) are capable of rendering the output string.
1105 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be
1106 rendered by one or more of the output devices mapped
1112 GraphicsConsoleConOutTestString (
1113 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1120 EFI_IMAGE_OUTPUT
*Blt
;
1125 while (WString
[Count
] != 0) {
1126 Status
= mHiiFont
->GetGlyph (
1139 if (EFI_ERROR (Status
)) {
1140 return EFI_UNSUPPORTED
;
1149 Returns information for an available text mode that the output device(s)
1152 Implements SIMPLE_TEXT_OUTPUT.QueryMode().
1153 It returnes information for an available text mode that the Graphics Console supports.
1154 In this driver,we only support text mode 80x25, which is defined as mode 0.
1156 @param This Protocol instance pointer.
1157 @param ModeNumber The mode number to return information on.
1158 @param Columns The returned columns of the requested mode.
1159 @param Rows The returned rows of the requested mode.
1161 @retval EFI_SUCCESS The requested mode information is returned.
1162 @retval EFI_UNSUPPORTED The mode number is not valid.
1167 GraphicsConsoleConOutQueryMode (
1168 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1169 IN UINTN ModeNumber
,
1174 GRAPHICS_CONSOLE_DEV
*Private
;
1178 if (ModeNumber
>= (UINTN
) This
->Mode
->MaxMode
) {
1179 return EFI_UNSUPPORTED
;
1182 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1183 Status
= EFI_SUCCESS
;
1185 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1187 *Columns
= Private
->ModeData
[ModeNumber
].Columns
;
1188 *Rows
= Private
->ModeData
[ModeNumber
].Rows
;
1190 if (*Columns
<= 0 && *Rows
<= 0) {
1191 Status
= EFI_UNSUPPORTED
;
1197 gBS
->RestoreTPL (OldTpl
);
1203 Sets the output device(s) to a specified mode.
1205 Implements SIMPLE_TEXT_OUTPUT.SetMode().
1206 Set the Graphics Console to a specified mode. In this driver, we only support mode 0.
1208 @param This Protocol instance pointer.
1209 @param ModeNumber The text mode to set.
1211 @retval EFI_SUCCESS The requested text mode is set.
1212 @retval EFI_DEVICE_ERROR The requested text mode cannot be set because of
1213 Graphics Console device error.
1214 @retval EFI_UNSUPPORTED The text mode number is not valid.
1219 GraphicsConsoleConOutSetMode (
1220 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1225 GRAPHICS_CONSOLE_DEV
*Private
;
1226 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1227 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*NewLineBuffer
;
1228 UINT32 HorizontalResolution
;
1229 UINT32 VerticalResolution
;
1230 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1231 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1236 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1238 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1239 GraphicsOutput
= Private
->GraphicsOutput
;
1240 UgaDraw
= Private
->UgaDraw
;
1241 ModeData
= &(Private
->ModeData
[ModeNumber
]);
1243 if (ModeData
->Columns
<= 0 && ModeData
->Rows
<= 0) {
1244 Status
= EFI_UNSUPPORTED
;
1249 // Make sure the requested mode number is supported
1251 if (ModeNumber
>= (UINTN
) This
->Mode
->MaxMode
) {
1252 Status
= EFI_UNSUPPORTED
;
1256 if (ModeData
->Columns
<= 0 && ModeData
->Rows
<= 0) {
1257 Status
= EFI_UNSUPPORTED
;
1261 // Attempt to allocate a line buffer for the requested mode number
1263 NewLineBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * ModeData
->Columns
* EFI_GLYPH_WIDTH
* EFI_GLYPH_HEIGHT
);
1265 if (NewLineBuffer
== NULL
) {
1267 // The new line buffer could not be allocated, so return an error.
1268 // No changes to the state of the current console have been made, so the current console is still valid
1270 Status
= EFI_OUT_OF_RESOURCES
;
1274 // If the mode has been set at least one other time, then LineBuffer will not be NULL
1276 if (Private
->LineBuffer
!= NULL
) {
1278 // Clear the current text window on the current graphics console
1280 This
->ClearScreen (This
);
1283 // If the new mode is the same as the old mode, then just return EFI_SUCCESS
1285 if ((INT32
) ModeNumber
== This
->Mode
->Mode
) {
1286 FreePool (NewLineBuffer
);
1287 Status
= EFI_SUCCESS
;
1291 // Otherwise, the size of the text console and/or the GOP/UGA mode will be changed,
1292 // so erase the cursor, and free the LineBuffer for the current mode
1296 FreePool (Private
->LineBuffer
);
1299 // Assign the current line buffer to the newly allocated line buffer
1301 Private
->LineBuffer
= NewLineBuffer
;
1303 if (GraphicsOutput
!= NULL
) {
1304 if (ModeData
->GopModeNumber
!= GraphicsOutput
->Mode
->Mode
) {
1306 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
1308 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeData
->GopModeNumber
);
1309 if (EFI_ERROR (Status
)) {
1311 // The mode set operation failed
1317 // The current graphics mode is correct, so simply clear the entire display
1319 Status
= GraphicsOutput
->Blt (
1328 ModeData
->GopHeight
,
1332 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1334 // Get the current UGA Draw mode information
1336 Status
= UgaDraw
->GetMode (
1338 &HorizontalResolution
,
1339 &VerticalResolution
,
1343 if (EFI_ERROR (Status
) || HorizontalResolution
!= ModeData
->GopWidth
|| VerticalResolution
!= ModeData
->GopHeight
) {
1345 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
1347 Status
= UgaDraw
->SetMode (
1350 ModeData
->GopHeight
,
1354 if (EFI_ERROR (Status
)) {
1356 // The mode set operation failed
1362 // The current graphics mode is correct, so simply clear the entire display
1364 Status
= UgaDraw
->Blt (
1366 (EFI_UGA_PIXEL
*) (UINTN
) &mEfiColors
[0],
1373 ModeData
->GopHeight
,
1380 // The new mode is valid, so commit the mode change
1382 This
->Mode
->Mode
= (INT32
) ModeNumber
;
1385 // Move the text cursor to the upper left hand corner of the display and enable it
1387 This
->SetCursorPosition (This
, 0, 0);
1389 Status
= EFI_SUCCESS
;
1392 gBS
->RestoreTPL (OldTpl
);
1398 Sets the background and foreground colors for the OutputString () and
1399 ClearScreen () functions.
1401 Implements SIMPLE_TEXT_OUTPUT.SetAttribute().
1403 @param This Protocol instance pointer.
1404 @param Attribute The attribute to set. Bits 0..3 are the foreground
1405 color, and bits 4..6 are the background color.
1406 All other bits are undefined and must be zero.
1408 @retval EFI_SUCCESS The requested attribute is set.
1409 @retval EFI_DEVICE_ERROR The requested attribute cannot be set due to Graphics Console port error.
1410 @retval EFI_UNSUPPORTED The attribute requested is not defined.
1415 GraphicsConsoleConOutSetAttribute (
1416 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1422 if ((Attribute
| 0xFF) != 0xFF) {
1423 return EFI_UNSUPPORTED
;
1426 if ((INT32
) Attribute
== This
->Mode
->Attribute
) {
1430 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1434 This
->Mode
->Attribute
= (INT32
) Attribute
;
1438 gBS
->RestoreTPL (OldTpl
);
1445 Clears the output device(s) display to the currently selected background
1448 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().
1450 @param This Protocol instance pointer.
1452 @retval EFI_SUCCESS The operation completed successfully.
1453 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
1454 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
1459 GraphicsConsoleConOutClearScreen (
1460 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
1464 GRAPHICS_CONSOLE_DEV
*Private
;
1465 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1466 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1467 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1468 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
1469 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
1472 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1474 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1475 GraphicsOutput
= Private
->GraphicsOutput
;
1476 UgaDraw
= Private
->UgaDraw
;
1477 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1479 GetTextColors (This
, &Foreground
, &Background
);
1480 if (GraphicsOutput
!= NULL
) {
1481 Status
= GraphicsOutput
->Blt (
1490 ModeData
->GopHeight
,
1493 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1494 Status
= UgaDraw
->Blt (
1496 (EFI_UGA_PIXEL
*) (UINTN
) &Background
,
1503 ModeData
->GopHeight
,
1507 Status
= EFI_UNSUPPORTED
;
1510 This
->Mode
->CursorColumn
= 0;
1511 This
->Mode
->CursorRow
= 0;
1515 gBS
->RestoreTPL (OldTpl
);
1522 Sets the current coordinates of the cursor position.
1524 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().
1526 @param This Protocol instance pointer.
1527 @param Column The position to set the cursor to. Must be greater than or
1528 equal to zero and less than the number of columns and rows
1530 @param Row The position to set the cursor to. Must be greater than or
1531 equal to zero and less than the number of columns and rows
1534 @retval EFI_SUCCESS The operation completed successfully.
1535 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
1536 @retval EFI_UNSUPPORTED The output device is not in a valid text mode, or the
1537 cursor position is invalid for the current mode.
1542 GraphicsConsoleConOutSetCursorPosition (
1543 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1548 GRAPHICS_CONSOLE_DEV
*Private
;
1549 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1553 Status
= EFI_SUCCESS
;
1555 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1557 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1558 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1560 if ((Column
>= ModeData
->Columns
) || (Row
>= ModeData
->Rows
)) {
1561 Status
= EFI_UNSUPPORTED
;
1565 if ((This
->Mode
->CursorColumn
== (INT32
) Column
) && (This
->Mode
->CursorRow
== (INT32
) Row
)) {
1566 Status
= EFI_SUCCESS
;
1572 This
->Mode
->CursorColumn
= (INT32
) Column
;
1573 This
->Mode
->CursorRow
= (INT32
) Row
;
1578 gBS
->RestoreTPL (OldTpl
);
1585 Makes the cursor visible or invisible.
1587 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
1589 @param This Protocol instance pointer.
1590 @param Visible If TRUE, the cursor is set to be visible, If FALSE,
1591 the cursor is set to be invisible.
1593 @retval EFI_SUCCESS The operation completed successfully.
1598 GraphicsConsoleConOutEnableCursor (
1599 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1605 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1609 This
->Mode
->CursorVisible
= Visible
;
1613 gBS
->RestoreTPL (OldTpl
);
1618 Gets Graphics Console devcie's foreground color and background color.
1620 @param This Protocol instance pointer.
1621 @param Foreground Returned text foreground color.
1622 @param Background Returned text background color.
1624 @retval EFI_SUCCESS It returned always.
1629 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1630 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Foreground
,
1631 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Background
1636 Attribute
= This
->Mode
->Attribute
& 0x7F;
1638 *Foreground
= mEfiColors
[Attribute
& 0x0f];
1639 *Background
= mEfiColors
[Attribute
>> 4];
1645 Draw Unicode string on the Graphics Console device's screen.
1647 @param This Protocol instance pointer.
1648 @param UnicodeWeight One Unicode string to be displayed.
1649 @param Count The count of Unicode string.
1651 @retval EFI_OUT_OF_RESOURCES If no memory resource to use.
1652 @retval EFI_UNSUPPORTED If no Graphics Output protocol and UGA Draw
1654 @retval EFI_SUCCESS Drawing Unicode string implemented successfully.
1658 DrawUnicodeWeightAtCursorN (
1659 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1660 IN CHAR16
*UnicodeWeight
,
1665 GRAPHICS_CONSOLE_DEV
*Private
;
1666 EFI_IMAGE_OUTPUT
*Blt
;
1668 EFI_FONT_DISPLAY_INFO
*FontInfo
;
1669 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1670 EFI_HII_ROW_INFO
*RowInfoArray
;
1671 UINTN RowInfoArraySize
;
1673 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1674 Blt
= (EFI_IMAGE_OUTPUT
*) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT
));
1676 return EFI_OUT_OF_RESOURCES
;
1679 Blt
->Width
= (UINT16
) (Private
->ModeData
[This
->Mode
->Mode
].GopWidth
);
1680 Blt
->Height
= (UINT16
) (Private
->ModeData
[This
->Mode
->Mode
].GopHeight
);
1682 String
= AllocateCopyPool ((Count
+ 1) * sizeof (CHAR16
), UnicodeWeight
);
1683 if (String
== NULL
) {
1685 return EFI_OUT_OF_RESOURCES
;
1688 // Set the end character
1690 *(String
+ Count
) = L
'\0';
1692 FontInfo
= (EFI_FONT_DISPLAY_INFO
*) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO
));
1693 if (FontInfo
== NULL
) {
1696 return EFI_OUT_OF_RESOURCES
;
1699 // Get current foreground and background colors.
1701 GetTextColors (This
, &FontInfo
->ForegroundColor
, &FontInfo
->BackgroundColor
);
1703 if (Private
->GraphicsOutput
!= NULL
) {
1705 // If Graphics Output protocol exists, using HII Font protocol to draw.
1707 Blt
->Image
.Screen
= Private
->GraphicsOutput
;
1709 Status
= mHiiFont
->StringToImage (
1711 EFI_HII_IGNORE_IF_NO_GLYPH
| EFI_HII_DIRECT_TO_SCREEN
,
1715 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1716 This
->Mode
->CursorRow
* EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1722 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1724 // If Graphics Output protocol cannot be found and PcdUgaConsumeSupport enabled,
1725 // using UGA Draw protocol to draw.
1727 ASSERT (Private
->UgaDraw
!= NULL
);
1729 UgaDraw
= Private
->UgaDraw
;
1731 Blt
->Image
.Bitmap
= AllocateZeroPool (Blt
->Width
* Blt
->Height
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
1732 if (Blt
->Image
.Bitmap
== NULL
) {
1735 return EFI_OUT_OF_RESOURCES
;
1738 RowInfoArray
= NULL
;
1740 // StringToImage only support blt'ing image to device using GOP protocol. If GOP is not supported in this platform,
1741 // we ask StringToImage to print the string to blt buffer, then blt to device using UgaDraw.
1743 Status
= mHiiFont
->StringToImage (
1745 EFI_HII_IGNORE_IF_NO_GLYPH
,
1749 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1750 This
->Mode
->CursorRow
* EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1756 if (!EFI_ERROR (Status
)) {
1758 // Line breaks are handled by caller of DrawUnicodeWeightAtCursorN, so the updated parameter RowInfoArraySize by StringToImage will
1759 // always be 1 or 0 (if there is no valid Unicode Char can be printed). ASSERT here to make sure.
1761 ASSERT (RowInfoArraySize
<= 1);
1763 Status
= UgaDraw
->Blt (
1765 (EFI_UGA_PIXEL
*) Blt
->Image
.Bitmap
,
1766 EfiUgaBltBufferToVideo
,
1767 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1768 (This
->Mode
->CursorRow
) * EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1769 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1770 (This
->Mode
->CursorRow
) * EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1771 RowInfoArray
[0].LineWidth
,
1772 RowInfoArray
[0].LineHeight
,
1773 Blt
->Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1777 FreePool (RowInfoArray
);
1778 FreePool (Blt
->Image
.Bitmap
);
1780 Status
= EFI_UNSUPPORTED
;
1786 if (String
!= NULL
) {
1789 if (FontInfo
!= NULL
) {
1790 FreePool (FontInfo
);
1796 Erase the cursor on the screen.
1798 @param This Protocol instance pointer.
1800 @retval EFI_SUCCESS The cursor is erased successfully.
1805 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
1808 GRAPHICS_CONSOLE_DEV
*Private
;
1809 EFI_SIMPLE_TEXT_OUTPUT_MODE
*CurrentMode
;
1812 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1813 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1814 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground
;
1815 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background
;
1816 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar
[EFI_GLYPH_HEIGHT
][EFI_GLYPH_WIDTH
];
1820 CurrentMode
= This
->Mode
;
1822 if (!CurrentMode
->CursorVisible
) {
1826 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1827 GraphicsOutput
= Private
->GraphicsOutput
;
1828 UgaDraw
= Private
->UgaDraw
;
1831 // In this driver, only narrow character was supported.
1834 // Blt a character to the screen
1836 GlyphX
= (CurrentMode
->CursorColumn
* EFI_GLYPH_WIDTH
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaX
;
1837 GlyphY
= (CurrentMode
->CursorRow
* EFI_GLYPH_HEIGHT
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaY
;
1838 if (GraphicsOutput
!= NULL
) {
1839 GraphicsOutput
->Blt (
1841 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltChar
,
1842 EfiBltVideoToBltBuffer
,
1849 EFI_GLYPH_WIDTH
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1851 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1854 (EFI_UGA_PIXEL
*) (UINTN
) BltChar
,
1855 EfiUgaVideoToBltBuffer
,
1862 EFI_GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)
1866 GetTextColors (This
, &Foreground
.Pixel
, &Background
.Pixel
);
1869 // Convert Monochrome bitmap of the Glyph to BltBuffer structure
1871 for (PosY
= 0; PosY
< EFI_GLYPH_HEIGHT
; PosY
++) {
1872 for (PosX
= 0; PosX
< EFI_GLYPH_WIDTH
; PosX
++) {
1873 if ((mCursorGlyph
.GlyphCol1
[PosY
] & (BIT0
<< PosX
)) != 0) {
1874 BltChar
[PosY
][EFI_GLYPH_WIDTH
- PosX
- 1].Raw
^= Foreground
.Raw
;
1879 if (GraphicsOutput
!= NULL
) {
1880 GraphicsOutput
->Blt (
1882 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltChar
,
1883 EfiBltBufferToVideo
,
1890 EFI_GLYPH_WIDTH
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1892 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1895 (EFI_UGA_PIXEL
*) (UINTN
) BltChar
,
1896 EfiUgaBltBufferToVideo
,
1903 EFI_GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)
1911 The user Entry Point for module GraphicsConsole. The user code starts with this function.
1913 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1914 @param[in] SystemTable A pointer to the EFI System Table.
1916 @retval EFI_SUCCESS The entry point is executed successfully.
1917 @return other Some error occurs when executing this entry point.
1922 InitializeGraphicsConsole (
1923 IN EFI_HANDLE ImageHandle
,
1924 IN EFI_SYSTEM_TABLE
*SystemTable
1930 // Install driver model protocol(s).
1932 Status
= EfiLibInstallDriverBindingComponentName2 (
1935 &gGraphicsConsoleDriverBinding
,
1937 &gGraphicsConsoleComponentName
,
1938 &gGraphicsConsoleComponentName2
1940 ASSERT_EFI_ERROR (Status
);