2 This is the main routine for initializing the Graphics Console support routines.
4 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "GraphicsConsole.h"
12 // Graphics Console Device Private Data template
14 GRAPHICS_CONSOLE_DEV mGraphicsConsoleDevTemplate
= {
15 GRAPHICS_CONSOLE_DEV_SIGNATURE
,
16 (EFI_GRAPHICS_OUTPUT_PROTOCOL
*) NULL
,
17 (EFI_UGA_DRAW_PROTOCOL
*) NULL
,
19 GraphicsConsoleConOutReset
,
20 GraphicsConsoleConOutOutputString
,
21 GraphicsConsoleConOutTestString
,
22 GraphicsConsoleConOutQueryMode
,
23 GraphicsConsoleConOutSetMode
,
24 GraphicsConsoleConOutSetAttribute
,
25 GraphicsConsoleConOutClearScreen
,
26 GraphicsConsoleConOutSetCursorPosition
,
27 GraphicsConsoleConOutEnableCursor
,
28 (EFI_SIMPLE_TEXT_OUTPUT_MODE
*) NULL
33 EFI_TEXT_ATTR(EFI_LIGHTGRAY
, EFI_BLACK
),
38 (GRAPHICS_CONSOLE_MODE_DATA
*) NULL
,
39 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) NULL
42 GRAPHICS_CONSOLE_MODE_DATA mGraphicsConsoleModeData
[] = {
45 // New modes can be added here.
46 // The last entry is specific for full screen mode.
51 EFI_HII_DATABASE_PROTOCOL
*mHiiDatabase
;
52 EFI_HII_FONT_PROTOCOL
*mHiiFont
;
53 EFI_HII_HANDLE mHiiHandle
;
54 VOID
*mHiiRegistration
;
56 EFI_GUID mFontPackageListGuid
= {0xf5f219d3, 0x7006, 0x4648, {0xac, 0x8d, 0xd6, 0x1d, 0xfb, 0x7b, 0xc6, 0xad}};
58 CHAR16 mCrLfString
[3] = { CHAR_CARRIAGE_RETURN
, CHAR_LINEFEED
, CHAR_NULL
};
60 EFI_GRAPHICS_OUTPUT_BLT_PIXEL mGraphicsEfiColors
[16] = {
64 {0x00, 0x00, 0x00, 0x00}, // BLACK
65 {0x98, 0x00, 0x00, 0x00}, // LIGHTBLUE
66 {0x00, 0x98, 0x00, 0x00}, // LIGHGREEN
67 {0x98, 0x98, 0x00, 0x00}, // LIGHCYAN
68 {0x00, 0x00, 0x98, 0x00}, // LIGHRED
69 {0x98, 0x00, 0x98, 0x00}, // MAGENTA
70 {0x00, 0x98, 0x98, 0x00}, // BROWN
71 {0x98, 0x98, 0x98, 0x00}, // LIGHTGRAY
72 {0x30, 0x30, 0x30, 0x00}, // DARKGRAY - BRIGHT BLACK
73 {0xff, 0x00, 0x00, 0x00}, // BLUE
74 {0x00, 0xff, 0x00, 0x00}, // LIME
75 {0xff, 0xff, 0x00, 0x00}, // CYAN
76 {0x00, 0x00, 0xff, 0x00}, // RED
77 {0xff, 0x00, 0xff, 0x00}, // FUCHSIA
78 {0x00, 0xff, 0xff, 0x00}, // YELLOW
79 {0xff, 0xff, 0xff, 0x00} // WHITE
82 EFI_NARROW_GLYPH mCursorGlyph
= {
85 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF }
88 CHAR16 SpaceStr
[] = { NARROW_CHAR
, ' ', 0 };
90 EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding
= {
91 GraphicsConsoleControllerDriverSupported
,
92 GraphicsConsoleControllerDriverStart
,
93 GraphicsConsoleControllerDriverStop
,
100 Test to see if Graphics Console could be supported on the Controller.
102 Graphics Console could be supported if Graphics Output Protocol or UGA Draw
103 Protocol exists on the Controller. (UGA Draw Protocol could be skipped
104 if PcdUgaConsumeSupport is set to FALSE.)
106 @param This Protocol instance pointer.
107 @param Controller Handle of device to test.
108 @param RemainingDevicePath Optional parameter use to pick a specific child
111 @retval EFI_SUCCESS This driver supports this device.
112 @retval other This driver does not support this device.
117 GraphicsConsoleControllerDriverSupported (
118 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
119 IN EFI_HANDLE Controller
,
120 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
124 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
125 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
126 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
128 GraphicsOutput
= NULL
;
131 // Open the IO Abstraction(s) needed to perform the supported test
133 Status
= gBS
->OpenProtocol (
135 &gEfiGraphicsOutputProtocolGuid
,
136 (VOID
**) &GraphicsOutput
,
137 This
->DriverBindingHandle
,
139 EFI_OPEN_PROTOCOL_BY_DRIVER
142 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
144 // Open Graphics Output Protocol failed, try to open UGA Draw Protocol
146 Status
= gBS
->OpenProtocol (
148 &gEfiUgaDrawProtocolGuid
,
150 This
->DriverBindingHandle
,
152 EFI_OPEN_PROTOCOL_BY_DRIVER
155 if (EFI_ERROR (Status
)) {
160 // We need to ensure that we do not layer on top of a virtual handle.
161 // We need to ensure that the handles produced by the conspliter do not
164 Status
= gBS
->OpenProtocol (
166 &gEfiDevicePathProtocolGuid
,
167 (VOID
**) &DevicePath
,
168 This
->DriverBindingHandle
,
170 EFI_OPEN_PROTOCOL_BY_DRIVER
172 if (!EFI_ERROR (Status
)) {
175 &gEfiDevicePathProtocolGuid
,
176 This
->DriverBindingHandle
,
184 // Does Hii Exist? If not, we aren't ready to run
186 Status
= EfiLocateHiiProtocol ();
189 // Close the I/O Abstraction(s) used to perform the supported test
192 if (GraphicsOutput
!= NULL
) {
195 &gEfiGraphicsOutputProtocolGuid
,
196 This
->DriverBindingHandle
,
199 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
202 &gEfiUgaDrawProtocolGuid
,
203 This
->DriverBindingHandle
,
211 Initialize all the text modes which the graphics console supports.
213 It returns information for available text modes that the graphics can support.
215 @param[in] HorizontalResolution The size of video screen in pixels in the X dimension.
216 @param[in] VerticalResolution The size of video screen in pixels in the Y dimension.
217 @param[in] GopModeNumber The graphics mode number which graphis console is based on.
218 @param[out] TextModeCount The total number of text modes that graphics console supports.
219 @param[out] TextModeData The buffer to the text modes column and row information.
220 Caller is responsible to free it when it's non-NULL.
222 @retval EFI_SUCCESS The supporting mode information is returned.
223 @retval EFI_INVALID_PARAMETER The parameters are invalid.
227 InitializeGraphicsConsoleTextMode (
228 IN UINT32 HorizontalResolution
,
229 IN UINT32 VerticalResolution
,
230 IN UINT32 GopModeNumber
,
231 OUT UINTN
*TextModeCount
,
232 OUT GRAPHICS_CONSOLE_MODE_DATA
**TextModeData
237 GRAPHICS_CONSOLE_MODE_DATA
*ModeBuffer
;
238 GRAPHICS_CONSOLE_MODE_DATA
*NewModeBuffer
;
244 if ((TextModeCount
== NULL
) || (TextModeData
== NULL
)) {
245 return EFI_INVALID_PARAMETER
;
248 Count
= sizeof (mGraphicsConsoleModeData
) / sizeof (GRAPHICS_CONSOLE_MODE_DATA
);
251 // Compute the maximum number of text Rows and Columns that this current graphics mode can support.
252 // To make graphics console work well, MaxColumns and MaxRows should not be zero.
254 MaxColumns
= HorizontalResolution
/ EFI_GLYPH_WIDTH
;
255 MaxRows
= VerticalResolution
/ EFI_GLYPH_HEIGHT
;
258 // According to UEFI spec, all output devices support at least 80x25 text mode.
260 ASSERT ((MaxColumns
>= 80) && (MaxRows
>= 25));
263 // Add full screen mode to the last entry.
265 mGraphicsConsoleModeData
[Count
- 1].Columns
= MaxColumns
;
266 mGraphicsConsoleModeData
[Count
- 1].Rows
= MaxRows
;
269 // Get defined mode buffer pointer.
271 ModeBuffer
= mGraphicsConsoleModeData
;
274 // Here we make sure that the final mode exposed does not include the duplicated modes,
275 // and does not include the invalid modes which exceed the max column and row.
276 // Reserve 2 modes for 80x25, 80x50 of graphics console.
278 NewModeBuffer
= AllocateZeroPool (sizeof (GRAPHICS_CONSOLE_MODE_DATA
) * (Count
+ 2));
279 ASSERT (NewModeBuffer
!= NULL
);
282 // Mode 0 and mode 1 is for 80x25, 80x50 according to UEFI spec.
286 NewModeBuffer
[ValidCount
].Columns
= 80;
287 NewModeBuffer
[ValidCount
].Rows
= 25;
288 NewModeBuffer
[ValidCount
].GopWidth
= HorizontalResolution
;
289 NewModeBuffer
[ValidCount
].GopHeight
= VerticalResolution
;
290 NewModeBuffer
[ValidCount
].GopModeNumber
= GopModeNumber
;
291 NewModeBuffer
[ValidCount
].DeltaX
= (HorizontalResolution
- (NewModeBuffer
[ValidCount
].Columns
* EFI_GLYPH_WIDTH
)) >> 1;
292 NewModeBuffer
[ValidCount
].DeltaY
= (VerticalResolution
- (NewModeBuffer
[ValidCount
].Rows
* EFI_GLYPH_HEIGHT
)) >> 1;
295 if ((MaxColumns
>= 80) && (MaxRows
>= 50)) {
296 NewModeBuffer
[ValidCount
].Columns
= 80;
297 NewModeBuffer
[ValidCount
].Rows
= 50;
298 NewModeBuffer
[ValidCount
].DeltaX
= (HorizontalResolution
- (80 * EFI_GLYPH_WIDTH
)) >> 1;
299 NewModeBuffer
[ValidCount
].DeltaY
= (VerticalResolution
- (50 * EFI_GLYPH_HEIGHT
)) >> 1;
301 NewModeBuffer
[ValidCount
].GopWidth
= HorizontalResolution
;
302 NewModeBuffer
[ValidCount
].GopHeight
= VerticalResolution
;
303 NewModeBuffer
[ValidCount
].GopModeNumber
= GopModeNumber
;
307 // Start from mode 2 to put the valid mode other than 80x25 and 80x50 in the output mode buffer.
309 for (Index
= 0; Index
< Count
; Index
++) {
310 if ((ModeBuffer
[Index
].Columns
== 0) || (ModeBuffer
[Index
].Rows
== 0) ||
311 (ModeBuffer
[Index
].Columns
> MaxColumns
) || (ModeBuffer
[Index
].Rows
> MaxRows
)) {
313 // Skip the pre-defined mode which is invalid or exceeds the max column and row.
317 for (ValidIndex
= 0; ValidIndex
< ValidCount
; ValidIndex
++) {
318 if ((ModeBuffer
[Index
].Columns
== NewModeBuffer
[ValidIndex
].Columns
) &&
319 (ModeBuffer
[Index
].Rows
== NewModeBuffer
[ValidIndex
].Rows
)) {
321 // Skip the duplicated mode.
326 if (ValidIndex
== ValidCount
) {
327 NewModeBuffer
[ValidCount
].Columns
= ModeBuffer
[Index
].Columns
;
328 NewModeBuffer
[ValidCount
].Rows
= ModeBuffer
[Index
].Rows
;
329 NewModeBuffer
[ValidCount
].GopWidth
= HorizontalResolution
;
330 NewModeBuffer
[ValidCount
].GopHeight
= VerticalResolution
;
331 NewModeBuffer
[ValidCount
].GopModeNumber
= GopModeNumber
;
332 NewModeBuffer
[ValidCount
].DeltaX
= (HorizontalResolution
- (NewModeBuffer
[ValidCount
].Columns
* EFI_GLYPH_WIDTH
)) >> 1;
333 NewModeBuffer
[ValidCount
].DeltaY
= (VerticalResolution
- (NewModeBuffer
[ValidCount
].Rows
* EFI_GLYPH_HEIGHT
)) >> 1;
339 for (Index
= 0; Index
< ValidCount
; Index
++) {
340 DEBUG ((EFI_D_INFO
, "Graphics - Mode %d, Column = %d, Row = %d\n",
341 Index
, NewModeBuffer
[Index
].Columns
, NewModeBuffer
[Index
].Rows
));
346 // Return valid mode count and mode information buffer.
348 *TextModeCount
= ValidCount
;
349 *TextModeData
= NewModeBuffer
;
354 Start this driver on Controller by opening Graphics Output protocol or
355 UGA Draw protocol, and installing Simple Text Out protocol on Controller.
356 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)
358 @param This Protocol instance pointer.
359 @param Controller Handle of device to bind driver to
360 @param RemainingDevicePath Optional parameter use to pick a specific child
363 @retval EFI_SUCCESS This driver is added to Controller.
364 @retval other This driver does not support this device.
369 GraphicsConsoleControllerDriverStart (
370 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
371 IN EFI_HANDLE Controller
,
372 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
376 GRAPHICS_CONSOLE_DEV
*Private
;
377 UINT32 HorizontalResolution
;
378 UINT32 VerticalResolution
;
384 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
*Mode
;
386 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
397 // Initialize the Graphics Console device instance
399 Private
= AllocateCopyPool (
400 sizeof (GRAPHICS_CONSOLE_DEV
),
401 &mGraphicsConsoleDevTemplate
403 if (Private
== NULL
) {
404 return EFI_OUT_OF_RESOURCES
;
407 Private
->SimpleTextOutput
.Mode
= &(Private
->SimpleTextOutputMode
);
409 Status
= gBS
->OpenProtocol (
411 &gEfiGraphicsOutputProtocolGuid
,
412 (VOID
**) &Private
->GraphicsOutput
,
413 This
->DriverBindingHandle
,
415 EFI_OPEN_PROTOCOL_BY_DRIVER
418 if (EFI_ERROR(Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
419 Status
= gBS
->OpenProtocol (
421 &gEfiUgaDrawProtocolGuid
,
422 (VOID
**) &Private
->UgaDraw
,
423 This
->DriverBindingHandle
,
425 EFI_OPEN_PROTOCOL_BY_DRIVER
429 if (EFI_ERROR (Status
)) {
433 HorizontalResolution
= PcdGet32 (PcdVideoHorizontalResolution
);
434 VerticalResolution
= PcdGet32 (PcdVideoVerticalResolution
);
436 if (Private
->GraphicsOutput
!= NULL
) {
438 // The console is build on top of Graphics Output Protocol, find the mode number
439 // for the user-defined mode; if there are multiple video devices,
440 // graphic console driver will set all the video devices to the same mode.
442 if ((HorizontalResolution
== 0x0) || (VerticalResolution
== 0x0)) {
444 // Find the highest resolution which GOP supports.
446 MaxMode
= Private
->GraphicsOutput
->Mode
->MaxMode
;
448 for (ModeIndex
= 0; ModeIndex
< MaxMode
; ModeIndex
++) {
449 Status
= Private
->GraphicsOutput
->QueryMode (
450 Private
->GraphicsOutput
,
455 if (!EFI_ERROR (Status
)) {
456 if ((Info
->HorizontalResolution
> HorizontalResolution
) ||
457 ((Info
->HorizontalResolution
== HorizontalResolution
) && (Info
->VerticalResolution
> VerticalResolution
))) {
458 HorizontalResolution
= Info
->HorizontalResolution
;
459 VerticalResolution
= Info
->VerticalResolution
;
460 ModeNumber
= ModeIndex
;
465 if ((HorizontalResolution
== 0x0) || (VerticalResolution
== 0x0)) {
466 Status
= EFI_UNSUPPORTED
;
471 // Use user-defined resolution
473 Status
= CheckModeSupported (
474 Private
->GraphicsOutput
,
475 HorizontalResolution
,
479 if (EFI_ERROR (Status
)) {
481 // if not supporting current mode, try 800x600 which is required by UEFI/EFI spec
483 HorizontalResolution
= 800;
484 VerticalResolution
= 600;
485 Status
= CheckModeSupported (
486 Private
->GraphicsOutput
,
487 HorizontalResolution
,
491 Mode
= Private
->GraphicsOutput
->Mode
;
492 if (EFI_ERROR (Status
) && Mode
->MaxMode
!= 0) {
494 // Set default mode failed or device don't support default mode, then get the current mode information
496 HorizontalResolution
= Mode
->Info
->HorizontalResolution
;
497 VerticalResolution
= Mode
->Info
->VerticalResolution
;
498 ModeNumber
= Mode
->Mode
;
502 if (ModeNumber
!= Private
->GraphicsOutput
->Mode
->Mode
) {
504 // Current graphics mode is not set or is not set to the mode which we has found,
505 // set the new graphic mode.
507 Status
= Private
->GraphicsOutput
->SetMode (Private
->GraphicsOutput
, ModeNumber
);
508 if (EFI_ERROR (Status
)) {
510 // The mode set operation failed
515 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
517 // At first try to set user-defined resolution
521 Status
= Private
->UgaDraw
->SetMode (
523 HorizontalResolution
,
528 if (EFI_ERROR (Status
)) {
530 // Try to set 800*600 which is required by UEFI/EFI spec
532 Status
= Private
->UgaDraw
->SetMode (
539 if (EFI_ERROR (Status
)) {
540 Status
= Private
->UgaDraw
->GetMode (
542 &HorizontalResolution
,
547 if (EFI_ERROR (Status
)) {
554 DEBUG ((EFI_D_INFO
, "GraphicsConsole video resolution %d x %d\n", HorizontalResolution
, VerticalResolution
));
557 // Initialize the mode which GraphicsConsole supports.
559 Status
= InitializeGraphicsConsoleTextMode (
560 HorizontalResolution
,
567 if (EFI_ERROR (Status
)) {
572 // Update the maximum number of modes
574 Private
->SimpleTextOutputMode
.MaxMode
= (INT32
) MaxMode
;
577 // Initialize the Mode of graphics console devices
580 DefaultColumn
= PcdGet32 (PcdConOutColumn
);
581 DefaultRow
= PcdGet32 (PcdConOutRow
);
584 for (Index
= 0; Index
< (INT32
)MaxMode
; Index
++) {
585 if (DefaultColumn
!= 0 && DefaultRow
!= 0) {
586 if ((Private
->ModeData
[Index
].Columns
== DefaultColumn
) &&
587 (Private
->ModeData
[Index
].Rows
== DefaultRow
)) {
592 if ((Private
->ModeData
[Index
].Columns
> Column
) &&
593 (Private
->ModeData
[Index
].Rows
> Row
)) {
594 Column
= Private
->ModeData
[Index
].Columns
;
595 Row
= Private
->ModeData
[Index
].Rows
;
600 Private
->SimpleTextOutput
.Mode
->Mode
= (INT32
)PreferMode
;
601 DEBUG ((DEBUG_INFO
, "Graphics Console Started, Mode: %d\n", PreferMode
));
604 // Install protocol interfaces for the Graphics Console device.
606 Status
= gBS
->InstallMultipleProtocolInterfaces (
608 &gEfiSimpleTextOutProtocolGuid
,
609 &Private
->SimpleTextOutput
,
614 if (EFI_ERROR (Status
)) {
616 // Close the GOP and UGA Draw Protocol
618 if (Private
->GraphicsOutput
!= NULL
) {
621 &gEfiGraphicsOutputProtocolGuid
,
622 This
->DriverBindingHandle
,
625 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
628 &gEfiUgaDrawProtocolGuid
,
629 This
->DriverBindingHandle
,
634 if (Private
->LineBuffer
!= NULL
) {
635 FreePool (Private
->LineBuffer
);
638 if (Private
->ModeData
!= NULL
) {
639 FreePool (Private
->ModeData
);
652 Stop this driver on Controller by removing Simple Text Out protocol
653 and closing the Graphics Output Protocol or UGA Draw protocol on Controller.
654 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)
657 @param This Protocol instance pointer.
658 @param Controller Handle of device to stop driver on
659 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
660 children is zero stop the entire bus driver.
661 @param ChildHandleBuffer List of Child Handles to Stop.
663 @retval EFI_SUCCESS This driver is removed Controller.
664 @retval EFI_NOT_STARTED Simple Text Out protocol could not be found the
666 @retval other This driver was not removed from this device.
671 GraphicsConsoleControllerDriverStop (
672 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
673 IN EFI_HANDLE Controller
,
674 IN UINTN NumberOfChildren
,
675 IN EFI_HANDLE
*ChildHandleBuffer
679 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
680 GRAPHICS_CONSOLE_DEV
*Private
;
682 Status
= gBS
->OpenProtocol (
684 &gEfiSimpleTextOutProtocolGuid
,
685 (VOID
**) &SimpleTextOutput
,
686 This
->DriverBindingHandle
,
688 EFI_OPEN_PROTOCOL_GET_PROTOCOL
690 if (EFI_ERROR (Status
)) {
691 return EFI_NOT_STARTED
;
694 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
696 Status
= gBS
->UninstallProtocolInterface (
698 &gEfiSimpleTextOutProtocolGuid
,
699 &Private
->SimpleTextOutput
702 if (!EFI_ERROR (Status
)) {
704 // Close the GOP or UGA IO Protocol
706 if (Private
->GraphicsOutput
!= NULL
) {
709 &gEfiGraphicsOutputProtocolGuid
,
710 This
->DriverBindingHandle
,
713 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
716 &gEfiUgaDrawProtocolGuid
,
717 This
->DriverBindingHandle
,
722 if (Private
->LineBuffer
!= NULL
) {
723 FreePool (Private
->LineBuffer
);
726 if (Private
->ModeData
!= NULL
) {
727 FreePool (Private
->ModeData
);
731 // Free our instance data
740 Check if the current specific mode supported the user defined resolution
741 for the Graphics Console device based on Graphics Output Protocol.
743 If yes, set the graphic devcice's current mode to this specific mode.
745 @param GraphicsOutput Graphics Output Protocol instance pointer.
746 @param HorizontalResolution User defined horizontal resolution
747 @param VerticalResolution User defined vertical resolution.
748 @param CurrentModeNumber Current specific mode to be check.
750 @retval EFI_SUCCESS The mode is supported.
751 @retval EFI_UNSUPPORTED The specific mode is out of range of graphics
753 @retval other The specific mode does not support user defined
754 resolution or failed to set the current mode to the
755 specific mode on graphics device.
760 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
761 IN UINT32 HorizontalResolution
,
762 IN UINT32 VerticalResolution
,
763 OUT UINT32
*CurrentModeNumber
769 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
772 Status
= EFI_SUCCESS
;
773 MaxMode
= GraphicsOutput
->Mode
->MaxMode
;
775 for (ModeNumber
= 0; ModeNumber
< MaxMode
; ModeNumber
++) {
776 Status
= GraphicsOutput
->QueryMode (
782 if (!EFI_ERROR (Status
)) {
783 if ((Info
->HorizontalResolution
== HorizontalResolution
) &&
784 (Info
->VerticalResolution
== VerticalResolution
)) {
785 if ((GraphicsOutput
->Mode
->Info
->HorizontalResolution
== HorizontalResolution
) &&
786 (GraphicsOutput
->Mode
->Info
->VerticalResolution
== VerticalResolution
)) {
788 // If video device has been set to this mode, we do not need to SetMode again
793 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeNumber
);
794 if (!EFI_ERROR (Status
)) {
804 if (ModeNumber
== GraphicsOutput
->Mode
->MaxMode
) {
805 Status
= EFI_UNSUPPORTED
;
808 *CurrentModeNumber
= ModeNumber
;
814 Locate HII Database protocol and HII Font protocol.
816 @retval EFI_SUCCESS HII Database protocol and HII Font protocol
817 are located successfully.
818 @return other Failed to locate HII Database protocol or
823 EfiLocateHiiProtocol (
829 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**) &mHiiDatabase
);
830 if (EFI_ERROR (Status
)) {
834 Status
= gBS
->LocateProtocol (&gEfiHiiFontProtocolGuid
, NULL
, (VOID
**) &mHiiFont
);
839 // Body of the STO functions
843 Reset the text output device hardware and optionally run diagnostics.
845 Implements SIMPLE_TEXT_OUTPUT.Reset().
846 If ExtendeVerification is TRUE, then perform dependent Graphics Console
847 device reset, and set display mode to mode 0.
848 If ExtendedVerification is FALSE, only set display mode to mode 0.
850 @param This Protocol instance pointer.
851 @param ExtendedVerification Indicates that the driver may perform a more
852 exhaustive verification operation of the device
855 @retval EFI_SUCCESS The text output device was reset.
856 @retval EFI_DEVICE_ERROR The text output device is not functioning correctly and
862 GraphicsConsoleConOutReset (
863 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
864 IN BOOLEAN ExtendedVerification
868 Status
= This
->SetMode (This
, 0);
869 if (EFI_ERROR (Status
)) {
872 Status
= This
->SetAttribute (This
, EFI_TEXT_ATTR (This
->Mode
->Attribute
& 0x0F, EFI_BACKGROUND_BLACK
));
878 Write a Unicode string to the output device.
880 Implements SIMPLE_TEXT_OUTPUT.OutputString().
881 The Unicode string will be converted to Glyphs and will be
882 sent to the Graphics Console.
884 @param This Protocol instance pointer.
885 @param WString The NULL-terminated Unicode string to be displayed
886 on the output device(s). All output devices must
887 also support the Unicode drawing defined in this file.
889 @retval EFI_SUCCESS The string was output to the device.
890 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output
892 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
894 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
895 characters in the Unicode string could not be
896 rendered and were skipped.
901 GraphicsConsoleConOutOutputString (
902 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
906 GRAPHICS_CONSOLE_DEV
*Private
;
907 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
908 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
917 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
918 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
923 INT32 OriginAttribute
;
926 if (This
->Mode
->Mode
== -1) {
928 // If current mode is not valid, return error.
930 return EFI_UNSUPPORTED
;
933 Status
= EFI_SUCCESS
;
935 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
939 Mode
= This
->Mode
->Mode
;
940 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
941 GraphicsOutput
= Private
->GraphicsOutput
;
942 UgaDraw
= Private
->UgaDraw
;
944 MaxColumn
= Private
->ModeData
[Mode
].Columns
;
945 MaxRow
= Private
->ModeData
[Mode
].Rows
;
946 DeltaX
= (UINTN
) Private
->ModeData
[Mode
].DeltaX
;
947 DeltaY
= (UINTN
) Private
->ModeData
[Mode
].DeltaY
;
948 Width
= MaxColumn
* EFI_GLYPH_WIDTH
;
949 Height
= (MaxRow
- 1) * EFI_GLYPH_HEIGHT
;
950 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
953 // The Attributes won't change when during the time OutputString is called
955 GetTextColors (This
, &Foreground
, &Background
);
964 OriginAttribute
= This
->Mode
->Attribute
;
966 while (*WString
!= L
'\0') {
968 if (*WString
== CHAR_BACKSPACE
) {
970 // If the cursor is at the left edge of the display, then move the cursor
973 if (This
->Mode
->CursorColumn
== 0 && This
->Mode
->CursorRow
> 0) {
974 This
->Mode
->CursorRow
--;
975 This
->Mode
->CursorColumn
= (INT32
) (MaxColumn
- 1);
976 This
->OutputString (This
, SpaceStr
);
978 This
->Mode
->CursorRow
--;
979 This
->Mode
->CursorColumn
= (INT32
) (MaxColumn
- 1);
980 } else if (This
->Mode
->CursorColumn
> 0) {
982 // If the cursor is not at the left edge of the display, then move the cursor
985 This
->Mode
->CursorColumn
--;
986 This
->OutputString (This
, SpaceStr
);
988 This
->Mode
->CursorColumn
--;
993 } else if (*WString
== CHAR_LINEFEED
) {
995 // If the cursor is at the bottom of the display, then scroll the display one
996 // row, and do not update the cursor position. Otherwise, move the cursor
999 if (This
->Mode
->CursorRow
== (INT32
) (MaxRow
- 1)) {
1000 if (GraphicsOutput
!= NULL
) {
1002 // Scroll Screen Up One Row
1004 GraphicsOutput
->Blt (
1009 DeltaY
+ EFI_GLYPH_HEIGHT
,
1018 // Print Blank Line at last line
1020 GraphicsOutput
->Blt (
1032 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1034 // Scroll Screen Up One Row
1041 DeltaY
+ EFI_GLYPH_HEIGHT
,
1050 // Print Blank Line at last line
1054 (EFI_UGA_PIXEL
*) (UINTN
) &Background
,
1066 This
->Mode
->CursorRow
++;
1071 } else if (*WString
== CHAR_CARRIAGE_RETURN
) {
1073 // Move the cursor to the beginning of the current row.
1075 This
->Mode
->CursorColumn
= 0;
1078 } else if (*WString
== WIDE_CHAR
) {
1080 This
->Mode
->Attribute
|= EFI_WIDE_ATTRIBUTE
;
1083 } else if (*WString
== NARROW_CHAR
) {
1085 This
->Mode
->Attribute
&= (~ (UINT32
) EFI_WIDE_ATTRIBUTE
);
1090 // Print the character at the current cursor position and move the cursor
1091 // right one column. If this moves the cursor past the right edge of the
1092 // display, then the line should wrap to the beginning of the next line. This
1093 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the
1094 // bottom of the display, and the line wraps, then the display will be scrolled
1096 // If wide char is going to be displayed, need to display one character at a time
1097 // Or, need to know the display length of a certain string.
1099 // Index is used to determine how many character width units (wide = 2, narrow = 1)
1100 // Count is used to determine how many characters are used regardless of their attributes
1102 for (Count
= 0, Index
= 0; (This
->Mode
->CursorColumn
+ Index
) < MaxColumn
; Count
++, Index
++) {
1103 if (WString
[Count
] == CHAR_NULL
||
1104 WString
[Count
] == CHAR_BACKSPACE
||
1105 WString
[Count
] == CHAR_LINEFEED
||
1106 WString
[Count
] == CHAR_CARRIAGE_RETURN
||
1107 WString
[Count
] == WIDE_CHAR
||
1108 WString
[Count
] == NARROW_CHAR
) {
1112 // Is the wide attribute on?
1114 if ((This
->Mode
->Attribute
& EFI_WIDE_ATTRIBUTE
) != 0) {
1116 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop
1120 // This is the end-case where if we are at column 79 and about to print a wide character
1121 // We should prevent this from happening because we will wrap inappropriately. We should
1122 // not print this character until the next line.
1124 if ((This
->Mode
->CursorColumn
+ Index
+ 1) > MaxColumn
) {
1131 Status
= DrawUnicodeWeightAtCursorN (This
, WString
, Count
);
1132 if (EFI_ERROR (Status
)) {
1136 // At the end of line, output carriage return and line feed
1139 This
->Mode
->CursorColumn
+= (INT32
) Index
;
1140 if (This
->Mode
->CursorColumn
> (INT32
) MaxColumn
) {
1141 This
->Mode
->CursorColumn
-= 2;
1142 This
->OutputString (This
, SpaceStr
);
1145 if (This
->Mode
->CursorColumn
>= (INT32
) MaxColumn
) {
1147 This
->OutputString (This
, mCrLfString
);
1153 This
->Mode
->Attribute
= OriginAttribute
;
1158 Status
= EFI_WARN_UNKNOWN_GLYPH
;
1161 gBS
->RestoreTPL (OldTpl
);
1167 Verifies that all characters in a Unicode string can be output to the
1170 Implements SIMPLE_TEXT_OUTPUT.TestString().
1171 If one of the characters in the *Wstring is neither valid valid Unicode
1172 drawing characters, not ASCII code, then this function will return
1175 @param This Protocol instance pointer.
1176 @param WString The NULL-terminated Unicode string to be examined for the output
1179 @retval EFI_SUCCESS The device(s) are capable of rendering the output string.
1180 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be
1181 rendered by one or more of the output devices mapped
1187 GraphicsConsoleConOutTestString (
1188 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1195 EFI_IMAGE_OUTPUT
*Blt
;
1200 while (WString
[Count
] != 0) {
1201 Status
= mHiiFont
->GetGlyph (
1214 if (EFI_ERROR (Status
)) {
1215 return EFI_UNSUPPORTED
;
1224 Returns information for an available text mode that the output device(s)
1227 Implements SIMPLE_TEXT_OUTPUT.QueryMode().
1228 It returnes information for an available text mode that the Graphics Console supports.
1229 In this driver,we only support text mode 80x25, which is defined as mode 0.
1231 @param This Protocol instance pointer.
1232 @param ModeNumber The mode number to return information on.
1233 @param Columns The returned columns of the requested mode.
1234 @param Rows The returned rows of the requested mode.
1236 @retval EFI_SUCCESS The requested mode information is returned.
1237 @retval EFI_UNSUPPORTED The mode number is not valid.
1242 GraphicsConsoleConOutQueryMode (
1243 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1244 IN UINTN ModeNumber
,
1249 GRAPHICS_CONSOLE_DEV
*Private
;
1253 if (ModeNumber
>= (UINTN
) This
->Mode
->MaxMode
) {
1254 return EFI_UNSUPPORTED
;
1257 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1258 Status
= EFI_SUCCESS
;
1260 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1262 *Columns
= Private
->ModeData
[ModeNumber
].Columns
;
1263 *Rows
= Private
->ModeData
[ModeNumber
].Rows
;
1265 if (*Columns
<= 0 || *Rows
<= 0) {
1266 Status
= EFI_UNSUPPORTED
;
1272 gBS
->RestoreTPL (OldTpl
);
1278 Sets the output device(s) to a specified mode.
1280 Implements SIMPLE_TEXT_OUTPUT.SetMode().
1281 Set the Graphics Console to a specified mode. In this driver, we only support mode 0.
1283 @param This Protocol instance pointer.
1284 @param ModeNumber The text mode to set.
1286 @retval EFI_SUCCESS The requested text mode is set.
1287 @retval EFI_DEVICE_ERROR The requested text mode cannot be set because of
1288 Graphics Console device error.
1289 @retval EFI_UNSUPPORTED The text mode number is not valid.
1294 GraphicsConsoleConOutSetMode (
1295 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1300 GRAPHICS_CONSOLE_DEV
*Private
;
1301 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1302 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*NewLineBuffer
;
1303 UINT32 HorizontalResolution
;
1304 UINT32 VerticalResolution
;
1305 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1306 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1311 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1313 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1314 GraphicsOutput
= Private
->GraphicsOutput
;
1315 UgaDraw
= Private
->UgaDraw
;
1318 // Make sure the requested mode number is supported
1320 if (ModeNumber
>= (UINTN
) This
->Mode
->MaxMode
) {
1321 Status
= EFI_UNSUPPORTED
;
1325 ModeData
= &(Private
->ModeData
[ModeNumber
]);
1327 if (ModeData
->Columns
<= 0 && ModeData
->Rows
<= 0) {
1328 Status
= EFI_UNSUPPORTED
;
1333 // If the mode has been set at least one other time, then LineBuffer will not be NULL
1335 if (Private
->LineBuffer
!= NULL
) {
1337 // If the new mode is the same as the old mode, then just return EFI_SUCCESS
1339 if ((INT32
) ModeNumber
== This
->Mode
->Mode
) {
1341 // Clear the current text window on the current graphics console
1343 This
->ClearScreen (This
);
1344 Status
= EFI_SUCCESS
;
1348 // Otherwise, the size of the text console and/or the GOP/UGA mode will be changed,
1349 // so erase the cursor, and free the LineBuffer for the current mode
1353 FreePool (Private
->LineBuffer
);
1357 // Attempt to allocate a line buffer for the requested mode number
1359 NewLineBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * ModeData
->Columns
* EFI_GLYPH_WIDTH
* EFI_GLYPH_HEIGHT
);
1361 if (NewLineBuffer
== NULL
) {
1363 // The new line buffer could not be allocated, so return an error.
1364 // No changes to the state of the current console have been made, so the current console is still valid
1366 Status
= EFI_OUT_OF_RESOURCES
;
1371 // Assign the current line buffer to the newly allocated line buffer
1373 Private
->LineBuffer
= NewLineBuffer
;
1375 if (GraphicsOutput
!= NULL
) {
1376 if (ModeData
->GopModeNumber
!= GraphicsOutput
->Mode
->Mode
) {
1378 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
1380 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeData
->GopModeNumber
);
1381 if (EFI_ERROR (Status
)) {
1383 // The mode set operation failed
1389 // The current graphics mode is correct, so simply clear the entire display
1391 Status
= GraphicsOutput
->Blt (
1393 &mGraphicsEfiColors
[0],
1400 ModeData
->GopHeight
,
1404 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1406 // Get the current UGA Draw mode information
1408 Status
= UgaDraw
->GetMode (
1410 &HorizontalResolution
,
1411 &VerticalResolution
,
1415 if (EFI_ERROR (Status
) || HorizontalResolution
!= ModeData
->GopWidth
|| VerticalResolution
!= ModeData
->GopHeight
) {
1417 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
1419 Status
= UgaDraw
->SetMode (
1422 ModeData
->GopHeight
,
1426 if (EFI_ERROR (Status
)) {
1428 // The mode set operation failed
1434 // The current graphics mode is correct, so simply clear the entire display
1436 Status
= UgaDraw
->Blt (
1438 (EFI_UGA_PIXEL
*) (UINTN
) &mGraphicsEfiColors
[0],
1445 ModeData
->GopHeight
,
1452 // The new mode is valid, so commit the mode change
1454 This
->Mode
->Mode
= (INT32
) ModeNumber
;
1457 // Move the text cursor to the upper left hand corner of the display and flush it
1459 This
->Mode
->CursorColumn
= 0;
1460 This
->Mode
->CursorRow
= 0;
1464 Status
= EFI_SUCCESS
;
1467 gBS
->RestoreTPL (OldTpl
);
1473 Sets the background and foreground colors for the OutputString () and
1474 ClearScreen () functions.
1476 Implements SIMPLE_TEXT_OUTPUT.SetAttribute().
1478 @param This Protocol instance pointer.
1479 @param Attribute The attribute to set. Bits 0..3 are the foreground
1480 color, and bits 4..6 are the background color.
1481 All other bits are undefined and must be zero.
1483 @retval EFI_SUCCESS The requested attribute is set.
1484 @retval EFI_DEVICE_ERROR The requested attribute cannot be set due to Graphics Console port error.
1485 @retval EFI_UNSUPPORTED The attribute requested is not defined.
1490 GraphicsConsoleConOutSetAttribute (
1491 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1497 if ((Attribute
| 0x7F) != 0x7F) {
1498 return EFI_UNSUPPORTED
;
1501 if ((INT32
) Attribute
== This
->Mode
->Attribute
) {
1505 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1509 This
->Mode
->Attribute
= (INT32
) Attribute
;
1513 gBS
->RestoreTPL (OldTpl
);
1520 Clears the output device(s) display to the currently selected background
1523 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().
1525 @param This Protocol instance pointer.
1527 @retval EFI_SUCCESS The operation completed successfully.
1528 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
1529 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
1534 GraphicsConsoleConOutClearScreen (
1535 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
1539 GRAPHICS_CONSOLE_DEV
*Private
;
1540 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1541 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1542 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1543 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
1544 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
1547 if (This
->Mode
->Mode
== -1) {
1549 // If current mode is not valid, return error.
1551 return EFI_UNSUPPORTED
;
1554 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1556 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1557 GraphicsOutput
= Private
->GraphicsOutput
;
1558 UgaDraw
= Private
->UgaDraw
;
1559 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1561 GetTextColors (This
, &Foreground
, &Background
);
1562 if (GraphicsOutput
!= NULL
) {
1563 Status
= GraphicsOutput
->Blt (
1572 ModeData
->GopHeight
,
1575 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1576 Status
= UgaDraw
->Blt (
1578 (EFI_UGA_PIXEL
*) (UINTN
) &Background
,
1585 ModeData
->GopHeight
,
1589 Status
= EFI_UNSUPPORTED
;
1592 This
->Mode
->CursorColumn
= 0;
1593 This
->Mode
->CursorRow
= 0;
1597 gBS
->RestoreTPL (OldTpl
);
1604 Sets the current coordinates of the cursor position.
1606 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().
1608 @param This Protocol instance pointer.
1609 @param Column The position to set the cursor to. Must be greater than or
1610 equal to zero and less than the number of columns and rows
1612 @param Row The position to set the cursor to. Must be greater than or
1613 equal to zero and less than the number of columns and rows
1616 @retval EFI_SUCCESS The operation completed successfully.
1617 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
1618 @retval EFI_UNSUPPORTED The output device is not in a valid text mode, or the
1619 cursor position is invalid for the current mode.
1624 GraphicsConsoleConOutSetCursorPosition (
1625 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1630 GRAPHICS_CONSOLE_DEV
*Private
;
1631 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1635 if (This
->Mode
->Mode
== -1) {
1637 // If current mode is not valid, return error.
1639 return EFI_UNSUPPORTED
;
1642 Status
= EFI_SUCCESS
;
1644 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1646 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1647 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1649 if ((Column
>= ModeData
->Columns
) || (Row
>= ModeData
->Rows
)) {
1650 Status
= EFI_UNSUPPORTED
;
1654 if ((This
->Mode
->CursorColumn
== (INT32
) Column
) && (This
->Mode
->CursorRow
== (INT32
) Row
)) {
1655 Status
= EFI_SUCCESS
;
1661 This
->Mode
->CursorColumn
= (INT32
) Column
;
1662 This
->Mode
->CursorRow
= (INT32
) Row
;
1667 gBS
->RestoreTPL (OldTpl
);
1674 Makes the cursor visible or invisible.
1676 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
1678 @param This Protocol instance pointer.
1679 @param Visible If TRUE, the cursor is set to be visible, If FALSE,
1680 the cursor is set to be invisible.
1682 @retval EFI_SUCCESS The operation completed successfully.
1683 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
1689 GraphicsConsoleConOutEnableCursor (
1690 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1696 if (This
->Mode
->Mode
== -1) {
1698 // If current mode is not valid, return error.
1700 return EFI_UNSUPPORTED
;
1703 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1707 This
->Mode
->CursorVisible
= Visible
;
1711 gBS
->RestoreTPL (OldTpl
);
1716 Gets Graphics Console devcie's foreground color and background color.
1718 @param This Protocol instance pointer.
1719 @param Foreground Returned text foreground color.
1720 @param Background Returned text background color.
1722 @retval EFI_SUCCESS It returned always.
1727 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1728 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Foreground
,
1729 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Background
1734 Attribute
= This
->Mode
->Attribute
& 0x7F;
1736 *Foreground
= mGraphicsEfiColors
[Attribute
& 0x0f];
1737 *Background
= mGraphicsEfiColors
[Attribute
>> 4];
1743 Draw Unicode string on the Graphics Console device's screen.
1745 @param This Protocol instance pointer.
1746 @param UnicodeWeight One Unicode string to be displayed.
1747 @param Count The count of Unicode string.
1749 @retval EFI_OUT_OF_RESOURCES If no memory resource to use.
1750 @retval EFI_UNSUPPORTED If no Graphics Output protocol and UGA Draw
1752 @retval EFI_SUCCESS Drawing Unicode string implemented successfully.
1756 DrawUnicodeWeightAtCursorN (
1757 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1758 IN CHAR16
*UnicodeWeight
,
1763 GRAPHICS_CONSOLE_DEV
*Private
;
1764 EFI_IMAGE_OUTPUT
*Blt
;
1766 EFI_FONT_DISPLAY_INFO
*FontInfo
;
1767 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1768 EFI_HII_ROW_INFO
*RowInfoArray
;
1769 UINTN RowInfoArraySize
;
1771 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1772 Blt
= (EFI_IMAGE_OUTPUT
*) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT
));
1774 return EFI_OUT_OF_RESOURCES
;
1777 Blt
->Width
= (UINT16
) (Private
->ModeData
[This
->Mode
->Mode
].GopWidth
);
1778 Blt
->Height
= (UINT16
) (Private
->ModeData
[This
->Mode
->Mode
].GopHeight
);
1780 String
= AllocateCopyPool ((Count
+ 1) * sizeof (CHAR16
), UnicodeWeight
);
1781 if (String
== NULL
) {
1783 return EFI_OUT_OF_RESOURCES
;
1786 // Set the end character
1788 *(String
+ Count
) = L
'\0';
1790 FontInfo
= (EFI_FONT_DISPLAY_INFO
*) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO
));
1791 if (FontInfo
== NULL
) {
1794 return EFI_OUT_OF_RESOURCES
;
1797 // Get current foreground and background colors.
1799 GetTextColors (This
, &FontInfo
->ForegroundColor
, &FontInfo
->BackgroundColor
);
1801 if (Private
->GraphicsOutput
!= NULL
) {
1803 // If Graphics Output protocol exists, using HII Font protocol to draw.
1805 Blt
->Image
.Screen
= Private
->GraphicsOutput
;
1807 Status
= mHiiFont
->StringToImage (
1809 EFI_HII_IGNORE_IF_NO_GLYPH
| EFI_HII_DIRECT_TO_SCREEN
| EFI_HII_IGNORE_LINE_BREAK
,
1813 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1814 This
->Mode
->CursorRow
* EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1820 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1822 // If Graphics Output protocol cannot be found and PcdUgaConsumeSupport enabled,
1823 // using UGA Draw protocol to draw.
1825 ASSERT (Private
->UgaDraw
!= NULL
);
1827 UgaDraw
= Private
->UgaDraw
;
1829 Blt
->Image
.Bitmap
= AllocateZeroPool (Blt
->Width
* Blt
->Height
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
1830 if (Blt
->Image
.Bitmap
== NULL
) {
1833 return EFI_OUT_OF_RESOURCES
;
1836 RowInfoArray
= NULL
;
1838 // StringToImage only support blt'ing image to device using GOP protocol. If GOP is not supported in this platform,
1839 // we ask StringToImage to print the string to blt buffer, then blt to device using UgaDraw.
1841 Status
= mHiiFont
->StringToImage (
1843 EFI_HII_IGNORE_IF_NO_GLYPH
| EFI_HII_IGNORE_LINE_BREAK
,
1847 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1848 This
->Mode
->CursorRow
* EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1854 if (!EFI_ERROR (Status
)) {
1856 // Line breaks are handled by caller of DrawUnicodeWeightAtCursorN, so the updated parameter RowInfoArraySize by StringToImage will
1857 // always be 1 or 0 (if there is no valid Unicode Char can be printed). ASSERT here to make sure.
1859 ASSERT (RowInfoArraySize
<= 1);
1861 Status
= UgaDraw
->Blt (
1863 (EFI_UGA_PIXEL
*) Blt
->Image
.Bitmap
,
1864 EfiUgaBltBufferToVideo
,
1865 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1866 (This
->Mode
->CursorRow
) * EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1867 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1868 (This
->Mode
->CursorRow
) * EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1869 RowInfoArray
[0].LineWidth
,
1870 RowInfoArray
[0].LineHeight
,
1871 Blt
->Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1875 FreePool (RowInfoArray
);
1876 FreePool (Blt
->Image
.Bitmap
);
1878 Status
= EFI_UNSUPPORTED
;
1884 if (String
!= NULL
) {
1887 if (FontInfo
!= NULL
) {
1888 FreePool (FontInfo
);
1894 Flush the cursor on the screen.
1896 If CursorVisible is FALSE, nothing to do and return directly.
1897 If CursorVisible is TRUE,
1898 i) If the cursor shows on screen, it will be erased.
1899 ii) If the cursor does not show on screen, it will be shown.
1901 @param This Protocol instance pointer.
1903 @retval EFI_SUCCESS The cursor is erased successfully.
1908 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
1911 GRAPHICS_CONSOLE_DEV
*Private
;
1912 EFI_SIMPLE_TEXT_OUTPUT_MODE
*CurrentMode
;
1915 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1916 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1917 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground
;
1918 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background
;
1919 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar
[EFI_GLYPH_HEIGHT
][EFI_GLYPH_WIDTH
];
1923 CurrentMode
= This
->Mode
;
1925 if (!CurrentMode
->CursorVisible
) {
1929 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1930 GraphicsOutput
= Private
->GraphicsOutput
;
1931 UgaDraw
= Private
->UgaDraw
;
1934 // In this driver, only narrow character was supported.
1937 // Blt a character to the screen
1939 GlyphX
= (CurrentMode
->CursorColumn
* EFI_GLYPH_WIDTH
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaX
;
1940 GlyphY
= (CurrentMode
->CursorRow
* EFI_GLYPH_HEIGHT
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaY
;
1941 if (GraphicsOutput
!= NULL
) {
1942 GraphicsOutput
->Blt (
1944 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltChar
,
1945 EfiBltVideoToBltBuffer
,
1952 EFI_GLYPH_WIDTH
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1954 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1957 (EFI_UGA_PIXEL
*) (UINTN
) BltChar
,
1958 EfiUgaVideoToBltBuffer
,
1965 EFI_GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)
1969 GetTextColors (This
, &Foreground
.Pixel
, &Background
.Pixel
);
1972 // Convert Monochrome bitmap of the Glyph to BltBuffer structure
1974 for (PosY
= 0; PosY
< EFI_GLYPH_HEIGHT
; PosY
++) {
1975 for (PosX
= 0; PosX
< EFI_GLYPH_WIDTH
; PosX
++) {
1976 if ((mCursorGlyph
.GlyphCol1
[PosY
] & (BIT0
<< PosX
)) != 0) {
1977 BltChar
[PosY
][EFI_GLYPH_WIDTH
- PosX
- 1].Raw
^= Foreground
.Raw
;
1982 if (GraphicsOutput
!= NULL
) {
1983 GraphicsOutput
->Blt (
1985 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltChar
,
1986 EfiBltBufferToVideo
,
1993 EFI_GLYPH_WIDTH
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1995 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1998 (EFI_UGA_PIXEL
*) (UINTN
) BltChar
,
1999 EfiUgaBltBufferToVideo
,
2006 EFI_GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)
2014 HII Database Protocol notification event handler.
2016 Register font package when HII Database Protocol has been installed.
2018 @param[in] Event Event whose notification function is being invoked.
2019 @param[in] Context Pointer to the notification function's context.
2023 RegisterFontPackage (
2029 EFI_HII_SIMPLE_FONT_PACKAGE_HDR
*SimplifiedFont
;
2030 UINT32 PackageLength
;
2033 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
2036 // Locate HII Database Protocol
2038 Status
= gBS
->LocateProtocol (
2039 &gEfiHiiDatabaseProtocolGuid
,
2041 (VOID
**) &HiiDatabase
2043 if (EFI_ERROR (Status
)) {
2048 // Add 4 bytes to the header for entire length for HiiAddPackages use only.
2050 // +--------------------------------+ <-- Package
2052 // | PackageLength(4 bytes) |
2054 // |--------------------------------| <-- SimplifiedFont
2056 // |EFI_HII_SIMPLE_FONT_PACKAGE_HDR |
2058 // |--------------------------------| <-- Location
2060 // | gUsStdNarrowGlyphData |
2062 // +--------------------------------+
2064 PackageLength
= sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR
) + mNarrowFontSize
+ 4;
2065 Package
= AllocateZeroPool (PackageLength
);
2066 ASSERT (Package
!= NULL
);
2068 WriteUnaligned32((UINT32
*) Package
,PackageLength
);
2069 SimplifiedFont
= (EFI_HII_SIMPLE_FONT_PACKAGE_HDR
*) (Package
+ 4);
2070 SimplifiedFont
->Header
.Length
= (UINT32
) (PackageLength
- 4);
2071 SimplifiedFont
->Header
.Type
= EFI_HII_PACKAGE_SIMPLE_FONTS
;
2072 SimplifiedFont
->NumberOfNarrowGlyphs
= (UINT16
) (mNarrowFontSize
/ sizeof (EFI_NARROW_GLYPH
));
2074 Location
= (UINT8
*) (&SimplifiedFont
->NumberOfWideGlyphs
+ 1);
2075 CopyMem (Location
, gUsStdNarrowGlyphData
, mNarrowFontSize
);
2078 // Add this simplified font package to a package list then install it.
2080 mHiiHandle
= HiiAddPackages (
2081 &mFontPackageListGuid
,
2086 ASSERT (mHiiHandle
!= NULL
);
2091 The user Entry Point for module GraphicsConsole. The user code starts with this function.
2093 @param[in] ImageHandle The firmware allocated handle for the EFI image.
2094 @param[in] SystemTable A pointer to the EFI System Table.
2096 @retval EFI_SUCCESS The entry point is executed successfully.
2097 @return other Some error occurs when executing this entry point.
2102 InitializeGraphicsConsole (
2103 IN EFI_HANDLE ImageHandle
,
2104 IN EFI_SYSTEM_TABLE
*SystemTable
2110 // Register notify function on HII Database Protocol to add font package.
2112 EfiCreateProtocolNotifyEvent (
2113 &gEfiHiiDatabaseProtocolGuid
,
2115 RegisterFontPackage
,
2121 // Install driver model protocol(s).
2123 Status
= EfiLibInstallDriverBindingComponentName2 (
2126 &gGraphicsConsoleDriverBinding
,
2128 &gGraphicsConsoleComponentName
,
2129 &gGraphicsConsoleComponentName2
2131 ASSERT_EFI_ERROR (Status
);