2 This is the main routine for initializing the Graphics Console support routines.
4 Copyright (c) 2006 - 2022, 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
= {
57 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 mGraphicsEfiColors
[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
158 if (EFI_ERROR (Status
)) {
163 // We need to ensure that we do not layer on top of a virtual handle.
164 // We need to ensure that the handles produced by the conspliter do not
167 Status
= gBS
->OpenProtocol (
169 &gEfiDevicePathProtocolGuid
,
170 (VOID
**)&DevicePath
,
171 This
->DriverBindingHandle
,
173 EFI_OPEN_PROTOCOL_BY_DRIVER
175 if (!EFI_ERROR (Status
)) {
178 &gEfiDevicePathProtocolGuid
,
179 This
->DriverBindingHandle
,
187 // Does Hii Exist? If not, we aren't ready to run
189 Status
= EfiLocateHiiProtocol ();
192 // Close the I/O Abstraction(s) used to perform the supported test
195 if (GraphicsOutput
!= NULL
) {
198 &gEfiGraphicsOutputProtocolGuid
,
199 This
->DriverBindingHandle
,
202 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
205 &gEfiUgaDrawProtocolGuid
,
206 This
->DriverBindingHandle
,
215 Initialize all the text modes which the graphics console supports.
217 It returns information for available text modes that the graphics can support.
219 @param[in] HorizontalResolution The size of video screen in pixels in the X dimension.
220 @param[in] VerticalResolution The size of video screen in pixels in the Y dimension.
221 @param[in] GopModeNumber The graphics mode number which graphics console is based on.
222 @param[out] TextModeCount The total number of text modes that graphics console supports.
223 @param[out] TextModeData The buffer to the text modes column and row information.
224 Caller is responsible to free it when it's non-NULL.
226 @retval EFI_SUCCESS The supporting mode information is returned.
227 @retval EFI_INVALID_PARAMETER The parameters are invalid.
231 InitializeGraphicsConsoleTextMode (
232 IN UINT32 HorizontalResolution
,
233 IN UINT32 VerticalResolution
,
234 IN UINT32 GopModeNumber
,
235 OUT UINTN
*TextModeCount
,
236 OUT GRAPHICS_CONSOLE_MODE_DATA
**TextModeData
241 GRAPHICS_CONSOLE_MODE_DATA
*ModeBuffer
;
242 GRAPHICS_CONSOLE_MODE_DATA
*NewModeBuffer
;
248 if ((TextModeCount
== NULL
) || (TextModeData
== NULL
)) {
249 return EFI_INVALID_PARAMETER
;
252 Count
= sizeof (mGraphicsConsoleModeData
) / sizeof (GRAPHICS_CONSOLE_MODE_DATA
);
255 // Compute the maximum number of text Rows and Columns that this current graphics mode can support.
256 // To make graphics console work well, MaxColumns and MaxRows should not be zero.
258 MaxColumns
= HorizontalResolution
/ EFI_GLYPH_WIDTH
;
259 MaxRows
= VerticalResolution
/ EFI_GLYPH_HEIGHT
;
262 // According to UEFI spec, all output devices support at least 80x25 text mode.
264 ASSERT ((MaxColumns
>= 80) && (MaxRows
>= 25));
267 // Add full screen mode to the last entry.
269 mGraphicsConsoleModeData
[Count
- 1].Columns
= MaxColumns
;
270 mGraphicsConsoleModeData
[Count
- 1].Rows
= MaxRows
;
273 // Get defined mode buffer pointer.
275 ModeBuffer
= mGraphicsConsoleModeData
;
278 // Here we make sure that the final mode exposed does not include the duplicated modes,
279 // and does not include the invalid modes which exceed the max column and row.
280 // Reserve 2 modes for 80x25, 80x50 of graphics console.
282 NewModeBuffer
= AllocateZeroPool (sizeof (GRAPHICS_CONSOLE_MODE_DATA
) * (Count
+ 2));
283 ASSERT (NewModeBuffer
!= NULL
);
286 // Mode 0 and mode 1 is for 80x25, 80x50 according to UEFI spec.
290 NewModeBuffer
[ValidCount
].Columns
= 80;
291 NewModeBuffer
[ValidCount
].Rows
= 25;
292 NewModeBuffer
[ValidCount
].GopWidth
= HorizontalResolution
;
293 NewModeBuffer
[ValidCount
].GopHeight
= VerticalResolution
;
294 NewModeBuffer
[ValidCount
].GopModeNumber
= GopModeNumber
;
295 NewModeBuffer
[ValidCount
].DeltaX
= (HorizontalResolution
- (NewModeBuffer
[ValidCount
].Columns
* EFI_GLYPH_WIDTH
)) >> 1;
296 NewModeBuffer
[ValidCount
].DeltaY
= (VerticalResolution
- (NewModeBuffer
[ValidCount
].Rows
* EFI_GLYPH_HEIGHT
)) >> 1;
299 if ((MaxColumns
>= 80) && (MaxRows
>= 50)) {
300 NewModeBuffer
[ValidCount
].Columns
= 80;
301 NewModeBuffer
[ValidCount
].Rows
= 50;
302 NewModeBuffer
[ValidCount
].DeltaX
= (HorizontalResolution
- (80 * EFI_GLYPH_WIDTH
)) >> 1;
303 NewModeBuffer
[ValidCount
].DeltaY
= (VerticalResolution
- (50 * EFI_GLYPH_HEIGHT
)) >> 1;
306 NewModeBuffer
[ValidCount
].GopWidth
= HorizontalResolution
;
307 NewModeBuffer
[ValidCount
].GopHeight
= VerticalResolution
;
308 NewModeBuffer
[ValidCount
].GopModeNumber
= GopModeNumber
;
312 // Start from mode 2 to put the valid mode other than 80x25 and 80x50 in the output mode buffer.
314 for (Index
= 0; Index
< Count
; Index
++) {
315 if ((ModeBuffer
[Index
].Columns
== 0) || (ModeBuffer
[Index
].Rows
== 0) ||
316 (ModeBuffer
[Index
].Columns
> MaxColumns
) || (ModeBuffer
[Index
].Rows
> MaxRows
))
319 // Skip the pre-defined mode which is invalid or exceeds the max column and row.
324 for (ValidIndex
= 0; ValidIndex
< ValidCount
; ValidIndex
++) {
325 if ((ModeBuffer
[Index
].Columns
== NewModeBuffer
[ValidIndex
].Columns
) &&
326 (ModeBuffer
[Index
].Rows
== NewModeBuffer
[ValidIndex
].Rows
))
329 // Skip the duplicated mode.
335 if (ValidIndex
== ValidCount
) {
336 NewModeBuffer
[ValidCount
].Columns
= ModeBuffer
[Index
].Columns
;
337 NewModeBuffer
[ValidCount
].Rows
= ModeBuffer
[Index
].Rows
;
338 NewModeBuffer
[ValidCount
].GopWidth
= HorizontalResolution
;
339 NewModeBuffer
[ValidCount
].GopHeight
= VerticalResolution
;
340 NewModeBuffer
[ValidCount
].GopModeNumber
= GopModeNumber
;
341 NewModeBuffer
[ValidCount
].DeltaX
= (HorizontalResolution
- (NewModeBuffer
[ValidCount
].Columns
* EFI_GLYPH_WIDTH
)) >> 1;
342 NewModeBuffer
[ValidCount
].DeltaY
= (VerticalResolution
- (NewModeBuffer
[ValidCount
].Rows
* EFI_GLYPH_HEIGHT
)) >> 1;
348 for (Index
= 0; Index
< ValidCount
; Index
++) {
351 "Graphics - Mode %d, Column = %d, Row = %d\n",
353 NewModeBuffer
[Index
].Columns
,
354 NewModeBuffer
[Index
].Rows
361 // Return valid mode count and mode information buffer.
363 *TextModeCount
= ValidCount
;
364 *TextModeData
= NewModeBuffer
;
369 Start this driver on Controller by opening Graphics Output protocol or
370 UGA Draw protocol, and installing Simple Text Out protocol on Controller.
371 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)
373 @param This Protocol instance pointer.
374 @param Controller Handle of device to bind driver to
375 @param RemainingDevicePath Optional parameter use to pick a specific child
378 @retval EFI_SUCCESS This driver is added to Controller.
379 @retval other This driver does not support this device.
384 GraphicsConsoleControllerDriverStart (
385 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
386 IN EFI_HANDLE Controller
,
387 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
391 GRAPHICS_CONSOLE_DEV
*Private
;
392 UINT32 HorizontalResolution
;
393 UINT32 VerticalResolution
;
399 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
*Mode
;
401 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
412 // Initialize the Graphics Console device instance
414 Private
= AllocateCopyPool (
415 sizeof (GRAPHICS_CONSOLE_DEV
),
416 &mGraphicsConsoleDevTemplate
418 if (Private
== NULL
) {
419 return EFI_OUT_OF_RESOURCES
;
422 Private
->SimpleTextOutput
.Mode
= &(Private
->SimpleTextOutputMode
);
424 Status
= gBS
->OpenProtocol (
426 &gEfiGraphicsOutputProtocolGuid
,
427 (VOID
**)&Private
->GraphicsOutput
,
428 This
->DriverBindingHandle
,
430 EFI_OPEN_PROTOCOL_BY_DRIVER
433 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
434 Status
= gBS
->OpenProtocol (
436 &gEfiUgaDrawProtocolGuid
,
437 (VOID
**)&Private
->UgaDraw
,
438 This
->DriverBindingHandle
,
440 EFI_OPEN_PROTOCOL_BY_DRIVER
444 if (EFI_ERROR (Status
)) {
448 HorizontalResolution
= PcdGet32 (PcdVideoHorizontalResolution
);
449 VerticalResolution
= PcdGet32 (PcdVideoVerticalResolution
);
451 if (Private
->GraphicsOutput
!= NULL
) {
453 // The console is build on top of Graphics Output Protocol, find the mode number
454 // for the user-defined mode; if there are multiple video devices,
455 // graphic console driver will set all the video devices to the same mode.
457 if ((HorizontalResolution
== 0x0) || (VerticalResolution
== 0x0)) {
459 // Find the highest resolution which GOP supports.
461 MaxMode
= Private
->GraphicsOutput
->Mode
->MaxMode
;
463 for (ModeIndex
= 0; ModeIndex
< MaxMode
; ModeIndex
++) {
464 Status
= Private
->GraphicsOutput
->QueryMode (
465 Private
->GraphicsOutput
,
470 if (!EFI_ERROR (Status
)) {
471 if ((Info
->HorizontalResolution
> HorizontalResolution
) ||
472 ((Info
->HorizontalResolution
== HorizontalResolution
) && (Info
->VerticalResolution
> VerticalResolution
)))
474 HorizontalResolution
= Info
->HorizontalResolution
;
475 VerticalResolution
= Info
->VerticalResolution
;
476 ModeNumber
= ModeIndex
;
483 if ((HorizontalResolution
== 0x0) || (VerticalResolution
== 0x0)) {
484 Status
= EFI_UNSUPPORTED
;
489 // Use user-defined resolution
491 Status
= CheckModeSupported (
492 Private
->GraphicsOutput
,
493 HorizontalResolution
,
497 if (EFI_ERROR (Status
)) {
499 // if not supporting current mode, try 800x600 which is required by UEFI/EFI spec
501 HorizontalResolution
= 800;
502 VerticalResolution
= 600;
503 Status
= CheckModeSupported (
504 Private
->GraphicsOutput
,
505 HorizontalResolution
,
509 Mode
= Private
->GraphicsOutput
->Mode
;
510 if (EFI_ERROR (Status
) && (Mode
->MaxMode
!= 0)) {
512 // If set default mode failed or device doesn't support default mode, then get the current mode information
514 HorizontalResolution
= Mode
->Info
->HorizontalResolution
;
515 VerticalResolution
= Mode
->Info
->VerticalResolution
;
516 ModeNumber
= Mode
->Mode
;
521 if (EFI_ERROR (Status
) || (ModeNumber
!= Private
->GraphicsOutput
->Mode
->Mode
)) {
523 // Current graphics mode is not set or is not set to the mode which we have found,
524 // set the new graphic mode.
526 Status
= Private
->GraphicsOutput
->SetMode (Private
->GraphicsOutput
, ModeNumber
);
527 if (EFI_ERROR (Status
)) {
529 // The mode set operation failed
534 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
536 // At first try to set user-defined resolution
540 Status
= Private
->UgaDraw
->SetMode (
542 HorizontalResolution
,
547 if (EFI_ERROR (Status
)) {
549 // Try to set 800*600 which is required by UEFI/EFI spec
551 Status
= Private
->UgaDraw
->SetMode (
558 if (EFI_ERROR (Status
)) {
559 Status
= Private
->UgaDraw
->GetMode (
561 &HorizontalResolution
,
566 if (EFI_ERROR (Status
)) {
573 DEBUG ((DEBUG_INFO
, "GraphicsConsole video resolution %d x %d\n", HorizontalResolution
, VerticalResolution
));
576 // Initialize the mode which GraphicsConsole supports.
578 Status
= InitializeGraphicsConsoleTextMode (
579 HorizontalResolution
,
586 if (EFI_ERROR (Status
)) {
591 // Update the maximum number of modes
593 Private
->SimpleTextOutputMode
.MaxMode
= (INT32
)MaxMode
;
596 // Initialize the Mode of graphics console devices
599 DefaultColumn
= PcdGet32 (PcdConOutColumn
);
600 DefaultRow
= PcdGet32 (PcdConOutRow
);
603 for (Index
= 0; Index
< (INT32
)MaxMode
; Index
++) {
604 if ((DefaultColumn
!= 0) && (DefaultRow
!= 0)) {
605 if ((Private
->ModeData
[Index
].Columns
== DefaultColumn
) &&
606 (Private
->ModeData
[Index
].Rows
== DefaultRow
))
612 if ((Private
->ModeData
[Index
].Columns
> Column
) &&
613 (Private
->ModeData
[Index
].Rows
> Row
))
615 Column
= Private
->ModeData
[Index
].Columns
;
616 Row
= Private
->ModeData
[Index
].Rows
;
622 Private
->SimpleTextOutput
.Mode
->Mode
= (INT32
)PreferMode
;
623 DEBUG ((DEBUG_INFO
, "Graphics Console Started, Mode: %d\n", PreferMode
));
626 // Install protocol interfaces for the Graphics Console device.
628 Status
= gBS
->InstallMultipleProtocolInterfaces (
630 &gEfiSimpleTextOutProtocolGuid
,
631 &Private
->SimpleTextOutput
,
636 if (EFI_ERROR (Status
)) {
638 // Close the GOP and UGA Draw Protocol
640 if (Private
->GraphicsOutput
!= NULL
) {
643 &gEfiGraphicsOutputProtocolGuid
,
644 This
->DriverBindingHandle
,
647 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
650 &gEfiUgaDrawProtocolGuid
,
651 This
->DriverBindingHandle
,
656 if (Private
->LineBuffer
!= NULL
) {
657 FreePool (Private
->LineBuffer
);
660 if (Private
->ModeData
!= NULL
) {
661 FreePool (Private
->ModeData
);
674 Stop this driver on Controller by removing Simple Text Out protocol
675 and closing the Graphics Output Protocol or UGA Draw protocol on Controller.
676 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)
679 @param This Protocol instance pointer.
680 @param Controller Handle of device to stop driver on
681 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
682 children is zero stop the entire bus driver.
683 @param ChildHandleBuffer List of Child Handles to Stop.
685 @retval EFI_SUCCESS This driver is removed Controller.
686 @retval EFI_NOT_STARTED Simple Text Out protocol could not be found the
688 @retval other This driver was not removed from this device.
693 GraphicsConsoleControllerDriverStop (
694 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
695 IN EFI_HANDLE Controller
,
696 IN UINTN NumberOfChildren
,
697 IN EFI_HANDLE
*ChildHandleBuffer
701 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
702 GRAPHICS_CONSOLE_DEV
*Private
;
704 Status
= gBS
->OpenProtocol (
706 &gEfiSimpleTextOutProtocolGuid
,
707 (VOID
**)&SimpleTextOutput
,
708 This
->DriverBindingHandle
,
710 EFI_OPEN_PROTOCOL_GET_PROTOCOL
712 if (EFI_ERROR (Status
)) {
713 return EFI_NOT_STARTED
;
716 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
718 Status
= gBS
->UninstallProtocolInterface (
720 &gEfiSimpleTextOutProtocolGuid
,
721 &Private
->SimpleTextOutput
724 if (!EFI_ERROR (Status
)) {
726 // Close the GOP or UGA IO Protocol
728 if (Private
->GraphicsOutput
!= NULL
) {
731 &gEfiGraphicsOutputProtocolGuid
,
732 This
->DriverBindingHandle
,
735 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
738 &gEfiUgaDrawProtocolGuid
,
739 This
->DriverBindingHandle
,
744 if (Private
->LineBuffer
!= NULL
) {
745 FreePool (Private
->LineBuffer
);
748 if (Private
->ModeData
!= NULL
) {
749 FreePool (Private
->ModeData
);
753 // Free our instance data
762 Check if the current specific mode supported the user defined resolution
763 for the Graphics Console device based on Graphics Output Protocol.
765 If yes, set the graphic device's current mode to this specific mode.
767 @param GraphicsOutput Graphics Output Protocol instance pointer.
768 @param HorizontalResolution User defined horizontal resolution
769 @param VerticalResolution User defined vertical resolution.
770 @param CurrentModeNumber Current specific mode to be check.
772 @retval EFI_SUCCESS The mode is supported.
773 @retval EFI_UNSUPPORTED The specific mode is out of range of graphics
775 @retval other The specific mode does not support user defined
776 resolution or failed to set the current mode to the
777 specific mode on graphics device.
782 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
783 IN UINT32 HorizontalResolution
,
784 IN UINT32 VerticalResolution
,
785 OUT UINT32
*CurrentModeNumber
791 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
794 Status
= EFI_SUCCESS
;
795 MaxMode
= GraphicsOutput
->Mode
->MaxMode
;
797 for (ModeNumber
= 0; ModeNumber
< MaxMode
; ModeNumber
++) {
798 Status
= GraphicsOutput
->QueryMode (
804 if (!EFI_ERROR (Status
)) {
805 if ((Info
->HorizontalResolution
== HorizontalResolution
) &&
806 (Info
->VerticalResolution
== VerticalResolution
))
808 if ((GraphicsOutput
->Mode
->Info
->HorizontalResolution
== HorizontalResolution
) &&
809 (GraphicsOutput
->Mode
->Info
->VerticalResolution
== VerticalResolution
))
812 // If video device has been set to this mode, we do not need to SetMode again
817 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeNumber
);
818 if (!EFI_ERROR (Status
)) {
829 if (ModeNumber
== GraphicsOutput
->Mode
->MaxMode
) {
830 Status
= EFI_UNSUPPORTED
;
833 *CurrentModeNumber
= ModeNumber
;
838 Locate HII Database protocol and HII Font protocol.
840 @retval EFI_SUCCESS HII Database protocol and HII Font protocol
841 are located successfully.
842 @return other Failed to locate HII Database protocol or
847 EfiLocateHiiProtocol (
853 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**)&mHiiDatabase
);
854 if (EFI_ERROR (Status
)) {
858 Status
= gBS
->LocateProtocol (&gEfiHiiFontProtocolGuid
, NULL
, (VOID
**)&mHiiFont
);
863 // Body of the STO functions
867 Reset the text output device hardware and optionally run diagnostics.
869 Implements SIMPLE_TEXT_OUTPUT.Reset().
870 If ExtendedVerification is TRUE, then perform dependent Graphics Console
871 device reset, and set display mode to mode 0.
872 If ExtendedVerification is FALSE, only set display mode to mode 0.
874 @param This Protocol instance pointer.
875 @param ExtendedVerification Indicates that the driver may perform a more
876 exhaustive verification operation of the device
879 @retval EFI_SUCCESS The text output device was reset.
880 @retval EFI_DEVICE_ERROR The text output device is not functioning correctly and
886 GraphicsConsoleConOutReset (
887 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
888 IN BOOLEAN ExtendedVerification
893 Status
= This
->SetMode (This
, 0);
894 if (EFI_ERROR (Status
)) {
898 Status
= This
->SetAttribute (This
, EFI_TEXT_ATTR (This
->Mode
->Attribute
& 0x0F, EFI_BACKGROUND_BLACK
));
903 Write a Unicode string to the output device.
905 Implements SIMPLE_TEXT_OUTPUT.OutputString().
906 The Unicode string will be converted to Glyphs and will be
907 sent to the Graphics Console.
909 @param This Protocol instance pointer.
910 @param WString The NULL-terminated Unicode string to be displayed
911 on the output device(s). All output devices must
912 also support the Unicode drawing defined in this file.
914 @retval EFI_SUCCESS The string was output to the device.
915 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output
917 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
919 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
920 characters in the Unicode string could not be
921 rendered and were skipped.
926 GraphicsConsoleConOutOutputString (
927 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
931 GRAPHICS_CONSOLE_DEV
*Private
;
932 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
933 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
942 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
943 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
948 INT32 OriginAttribute
;
951 if (This
->Mode
->Mode
== -1) {
953 // If current mode is not valid, return error.
955 return EFI_UNSUPPORTED
;
958 Status
= EFI_SUCCESS
;
960 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
964 Mode
= This
->Mode
->Mode
;
965 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
966 GraphicsOutput
= Private
->GraphicsOutput
;
967 UgaDraw
= Private
->UgaDraw
;
969 MaxColumn
= Private
->ModeData
[Mode
].Columns
;
970 MaxRow
= Private
->ModeData
[Mode
].Rows
;
971 DeltaX
= (UINTN
)Private
->ModeData
[Mode
].DeltaX
;
972 DeltaY
= (UINTN
)Private
->ModeData
[Mode
].DeltaY
;
973 Width
= MaxColumn
* EFI_GLYPH_WIDTH
;
974 Height
= (MaxRow
- 1) * EFI_GLYPH_HEIGHT
;
975 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
978 // The Attributes won't change when during the time OutputString is called
980 GetTextColors (This
, &Foreground
, &Background
);
989 OriginAttribute
= This
->Mode
->Attribute
;
991 while (*WString
!= L
'\0') {
992 if (*WString
== CHAR_BACKSPACE
) {
994 // If the cursor is at the left edge of the display, then move the cursor
997 if ((This
->Mode
->CursorColumn
== 0) && (This
->Mode
->CursorRow
> 0)) {
998 This
->Mode
->CursorRow
--;
999 This
->Mode
->CursorColumn
= (INT32
)(MaxColumn
- 1);
1000 This
->OutputString (This
, SpaceStr
);
1002 This
->Mode
->CursorRow
--;
1003 This
->Mode
->CursorColumn
= (INT32
)(MaxColumn
- 1);
1004 } else if (This
->Mode
->CursorColumn
> 0) {
1006 // If the cursor is not at the left edge of the display, then move the cursor
1009 This
->Mode
->CursorColumn
--;
1010 This
->OutputString (This
, SpaceStr
);
1012 This
->Mode
->CursorColumn
--;
1016 } else if (*WString
== CHAR_LINEFEED
) {
1018 // If the cursor is at the bottom of the display, then scroll the display one
1019 // row, and do not update the cursor position. Otherwise, move the cursor
1022 if (This
->Mode
->CursorRow
== (INT32
)(MaxRow
- 1)) {
1023 if (GraphicsOutput
!= NULL
) {
1025 // Scroll Screen Up One Row
1027 GraphicsOutput
->Blt (
1032 DeltaY
+ EFI_GLYPH_HEIGHT
,
1041 // Print Blank Line at last line
1043 GraphicsOutput
->Blt (
1055 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1057 // Scroll Screen Up One Row
1064 DeltaY
+ EFI_GLYPH_HEIGHT
,
1073 // Print Blank Line at last line
1077 (EFI_UGA_PIXEL
*)(UINTN
)&Background
,
1089 This
->Mode
->CursorRow
++;
1093 } else if (*WString
== CHAR_CARRIAGE_RETURN
) {
1095 // Move the cursor to the beginning of the current row.
1097 This
->Mode
->CursorColumn
= 0;
1099 } else if (*WString
== WIDE_CHAR
) {
1100 This
->Mode
->Attribute
|= EFI_WIDE_ATTRIBUTE
;
1102 } else if (*WString
== NARROW_CHAR
) {
1103 This
->Mode
->Attribute
&= (~(UINT32
)EFI_WIDE_ATTRIBUTE
);
1107 // Print the character at the current cursor position and move the cursor
1108 // right one column. If this moves the cursor past the right edge of the
1109 // display, then the line should wrap to the beginning of the next line. This
1110 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the
1111 // bottom of the display, and the line wraps, then the display will be scrolled
1113 // If wide char is going to be displayed, need to display one character at a time
1114 // Or, need to know the display length of a certain string.
1116 // Index is used to determine how many character width units (wide = 2, narrow = 1)
1117 // Count is used to determine how many characters are used regardless of their attributes
1119 for (Count
= 0, Index
= 0; (This
->Mode
->CursorColumn
+ Index
) < MaxColumn
; Count
++, Index
++) {
1120 if ((WString
[Count
] == CHAR_NULL
) ||
1121 (WString
[Count
] == CHAR_BACKSPACE
) ||
1122 (WString
[Count
] == CHAR_LINEFEED
) ||
1123 (WString
[Count
] == CHAR_CARRIAGE_RETURN
) ||
1124 (WString
[Count
] == WIDE_CHAR
) ||
1125 (WString
[Count
] == NARROW_CHAR
))
1131 // Is the wide attribute on?
1133 if ((This
->Mode
->Attribute
& EFI_WIDE_ATTRIBUTE
) != 0) {
1135 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop
1139 // This is the end-case where if we are at column 79 and about to print a wide character
1140 // We should prevent this from happening because we will wrap inappropriately. We should
1141 // not print this character until the next line.
1143 if ((This
->Mode
->CursorColumn
+ Index
+ 1) > MaxColumn
) {
1150 Status
= DrawUnicodeWeightAtCursorN (This
, WString
, Count
);
1151 if (EFI_ERROR (Status
)) {
1156 // At the end of line, output carriage return and line feed
1159 This
->Mode
->CursorColumn
+= (INT32
)Index
;
1160 if (This
->Mode
->CursorColumn
> (INT32
)MaxColumn
) {
1161 This
->Mode
->CursorColumn
-= 2;
1162 This
->OutputString (This
, SpaceStr
);
1165 if (This
->Mode
->CursorColumn
>= (INT32
)MaxColumn
) {
1167 This
->OutputString (This
, mCrLfString
);
1173 This
->Mode
->Attribute
= OriginAttribute
;
1178 Status
= EFI_WARN_UNKNOWN_GLYPH
;
1181 gBS
->RestoreTPL (OldTpl
);
1186 Verifies that all characters in a Unicode string can be output to the
1189 Implements SIMPLE_TEXT_OUTPUT.TestString().
1190 If one of the characters in the *Wstring is neither valid valid Unicode
1191 drawing characters, not ASCII code, then this function will return
1194 @param This Protocol instance pointer.
1195 @param WString The NULL-terminated Unicode string to be examined for the output
1198 @retval EFI_SUCCESS The device(s) are capable of rendering the output string.
1199 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be
1200 rendered by one or more of the output devices mapped
1206 GraphicsConsoleConOutTestString (
1207 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1214 EFI_IMAGE_OUTPUT
*Blt
;
1219 while (WString
[Count
] != 0) {
1220 Status
= mHiiFont
->GetGlyph (
1234 if (EFI_ERROR (Status
)) {
1235 return EFI_UNSUPPORTED
;
1243 Returns information for an available text mode that the output device(s)
1246 Implements SIMPLE_TEXT_OUTPUT.QueryMode().
1247 It returnes information for an available text mode that the Graphics Console supports.
1248 In this driver,we only support text mode 80x25, which is defined as mode 0.
1250 @param This Protocol instance pointer.
1251 @param ModeNumber The mode number to return information on.
1252 @param Columns The returned columns of the requested mode.
1253 @param Rows The returned rows of the requested mode.
1255 @retval EFI_SUCCESS The requested mode information is returned.
1256 @retval EFI_UNSUPPORTED The mode number is not valid.
1261 GraphicsConsoleConOutQueryMode (
1262 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1263 IN UINTN ModeNumber
,
1268 GRAPHICS_CONSOLE_DEV
*Private
;
1272 if (ModeNumber
>= (UINTN
)This
->Mode
->MaxMode
) {
1273 return EFI_UNSUPPORTED
;
1276 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1277 Status
= EFI_SUCCESS
;
1279 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1281 *Columns
= Private
->ModeData
[ModeNumber
].Columns
;
1282 *Rows
= Private
->ModeData
[ModeNumber
].Rows
;
1284 if ((*Columns
<= 0) || (*Rows
<= 0)) {
1285 Status
= EFI_UNSUPPORTED
;
1290 gBS
->RestoreTPL (OldTpl
);
1295 Sets the output device(s) to a specified mode.
1297 Implements SIMPLE_TEXT_OUTPUT.SetMode().
1298 Set the Graphics Console to a specified mode. In this driver, we only support mode 0.
1300 @param This Protocol instance pointer.
1301 @param ModeNumber The text mode to set.
1303 @retval EFI_SUCCESS The requested text mode is set.
1304 @retval EFI_DEVICE_ERROR The requested text mode cannot be set because of
1305 Graphics Console device error.
1306 @retval EFI_UNSUPPORTED The text mode number is not valid.
1311 GraphicsConsoleConOutSetMode (
1312 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1317 GRAPHICS_CONSOLE_DEV
*Private
;
1318 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1319 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*NewLineBuffer
;
1320 UINT32 HorizontalResolution
;
1321 UINT32 VerticalResolution
;
1322 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1323 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1328 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1330 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1331 GraphicsOutput
= Private
->GraphicsOutput
;
1332 UgaDraw
= Private
->UgaDraw
;
1335 // Make sure the requested mode number is supported
1337 if (ModeNumber
>= (UINTN
)This
->Mode
->MaxMode
) {
1338 Status
= EFI_UNSUPPORTED
;
1342 ModeData
= &(Private
->ModeData
[ModeNumber
]);
1344 if ((ModeData
->Columns
<= 0) && (ModeData
->Rows
<= 0)) {
1345 Status
= EFI_UNSUPPORTED
;
1350 // If the mode has been set at least one other time, then LineBuffer will not be NULL
1352 if (Private
->LineBuffer
!= NULL
) {
1354 // If the new mode is the same as the old mode, then just return EFI_SUCCESS
1356 if ((INT32
)ModeNumber
== This
->Mode
->Mode
) {
1358 // Clear the current text window on the current graphics console
1360 This
->ClearScreen (This
);
1361 Status
= EFI_SUCCESS
;
1366 // Otherwise, the size of the text console and/or the GOP/UGA mode will be changed,
1367 // so erase the cursor, and free the LineBuffer for the current mode
1371 FreePool (Private
->LineBuffer
);
1375 // Attempt to allocate a line buffer for the requested mode number
1377 NewLineBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * ModeData
->Columns
* EFI_GLYPH_WIDTH
* EFI_GLYPH_HEIGHT
);
1379 if (NewLineBuffer
== NULL
) {
1381 // The new line buffer could not be allocated, so return an error.
1382 // No changes to the state of the current console have been made, so the current console is still valid
1384 Status
= EFI_OUT_OF_RESOURCES
;
1389 // Assign the current line buffer to the newly allocated line buffer
1391 Private
->LineBuffer
= NewLineBuffer
;
1393 if (GraphicsOutput
!= NULL
) {
1394 if (ModeData
->GopModeNumber
!= GraphicsOutput
->Mode
->Mode
) {
1396 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
1398 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeData
->GopModeNumber
);
1399 if (EFI_ERROR (Status
)) {
1401 // The mode set operation failed
1407 // The current graphics mode is correct, so simply clear the entire display
1409 Status
= GraphicsOutput
->Blt (
1411 &mGraphicsEfiColors
[0],
1418 ModeData
->GopHeight
,
1422 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1424 // Get the current UGA Draw mode information
1426 Status
= UgaDraw
->GetMode (
1428 &HorizontalResolution
,
1429 &VerticalResolution
,
1433 if (EFI_ERROR (Status
) || (HorizontalResolution
!= ModeData
->GopWidth
) || (VerticalResolution
!= ModeData
->GopHeight
)) {
1435 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
1437 Status
= UgaDraw
->SetMode (
1440 ModeData
->GopHeight
,
1444 if (EFI_ERROR (Status
)) {
1446 // The mode set operation failed
1452 // The current graphics mode is correct, so simply clear the entire display
1454 Status
= UgaDraw
->Blt (
1456 (EFI_UGA_PIXEL
*)(UINTN
)&mGraphicsEfiColors
[0],
1463 ModeData
->GopHeight
,
1470 // The new mode is valid, so commit the mode change
1472 This
->Mode
->Mode
= (INT32
)ModeNumber
;
1475 // Move the text cursor to the upper left hand corner of the display and flush it
1477 This
->Mode
->CursorColumn
= 0;
1478 This
->Mode
->CursorRow
= 0;
1482 Status
= EFI_SUCCESS
;
1485 gBS
->RestoreTPL (OldTpl
);
1490 Sets the background and foreground colors for the OutputString () and
1491 ClearScreen () functions.
1493 Implements SIMPLE_TEXT_OUTPUT.SetAttribute().
1495 @param This Protocol instance pointer.
1496 @param Attribute The attribute to set. Bits 0..3 are the foreground
1497 color, and bits 4..6 are the background color.
1498 All other bits are undefined and must be zero.
1500 @retval EFI_SUCCESS The requested attribute is set.
1501 @retval EFI_DEVICE_ERROR The requested attribute cannot be set due to Graphics Console port error.
1502 @retval EFI_UNSUPPORTED The attribute requested is not defined.
1507 GraphicsConsoleConOutSetAttribute (
1508 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1514 if ((Attribute
| 0x7F) != 0x7F) {
1515 return EFI_UNSUPPORTED
;
1518 if ((INT32
)Attribute
== This
->Mode
->Attribute
) {
1522 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1526 This
->Mode
->Attribute
= (INT32
)Attribute
;
1530 gBS
->RestoreTPL (OldTpl
);
1536 Clears the output device(s) display to the currently selected background
1539 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().
1541 @param This Protocol instance pointer.
1543 @retval EFI_SUCCESS The operation completed successfully.
1544 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
1545 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
1550 GraphicsConsoleConOutClearScreen (
1551 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
1555 GRAPHICS_CONSOLE_DEV
*Private
;
1556 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1557 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1558 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1559 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
1560 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
1563 if (This
->Mode
->Mode
== -1) {
1565 // If current mode is not valid, return error.
1567 return EFI_UNSUPPORTED
;
1570 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1572 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1573 GraphicsOutput
= Private
->GraphicsOutput
;
1574 UgaDraw
= Private
->UgaDraw
;
1575 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1577 GetTextColors (This
, &Foreground
, &Background
);
1578 if (GraphicsOutput
!= NULL
) {
1579 Status
= GraphicsOutput
->Blt (
1588 ModeData
->GopHeight
,
1591 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1592 Status
= UgaDraw
->Blt (
1594 (EFI_UGA_PIXEL
*)(UINTN
)&Background
,
1601 ModeData
->GopHeight
,
1605 Status
= EFI_UNSUPPORTED
;
1608 This
->Mode
->CursorColumn
= 0;
1609 This
->Mode
->CursorRow
= 0;
1613 gBS
->RestoreTPL (OldTpl
);
1619 Sets the current coordinates of the cursor position.
1621 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().
1623 @param This Protocol instance pointer.
1624 @param Column The position to set the cursor to. Must be greater than or
1625 equal to zero and less than the number of columns and rows
1627 @param Row The position to set the cursor to. Must be greater than or
1628 equal to zero and less than the number of columns and rows
1631 @retval EFI_SUCCESS The operation completed successfully.
1632 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
1633 @retval EFI_UNSUPPORTED The output device is not in a valid text mode, or the
1634 cursor position is invalid for the current mode.
1639 GraphicsConsoleConOutSetCursorPosition (
1640 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1645 GRAPHICS_CONSOLE_DEV
*Private
;
1646 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1650 if (This
->Mode
->Mode
== -1) {
1652 // If current mode is not valid, return error.
1654 return EFI_UNSUPPORTED
;
1657 Status
= EFI_SUCCESS
;
1659 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1661 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1662 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1664 if ((Column
>= ModeData
->Columns
) || (Row
>= ModeData
->Rows
)) {
1665 Status
= EFI_UNSUPPORTED
;
1669 if ((This
->Mode
->CursorColumn
== (INT32
)Column
) && (This
->Mode
->CursorRow
== (INT32
)Row
)) {
1670 Status
= EFI_SUCCESS
;
1676 This
->Mode
->CursorColumn
= (INT32
)Column
;
1677 This
->Mode
->CursorRow
= (INT32
)Row
;
1682 gBS
->RestoreTPL (OldTpl
);
1688 Makes the cursor visible or invisible.
1690 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
1692 @param This Protocol instance pointer.
1693 @param Visible If TRUE, the cursor is set to be visible, If FALSE,
1694 the cursor is set to be invisible.
1696 @retval EFI_SUCCESS The operation completed successfully.
1697 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
1703 GraphicsConsoleConOutEnableCursor (
1704 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1710 if (This
->Mode
->Mode
== -1) {
1712 // If current mode is not valid, return error.
1714 return EFI_UNSUPPORTED
;
1717 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1721 This
->Mode
->CursorVisible
= Visible
;
1725 gBS
->RestoreTPL (OldTpl
);
1730 Gets Graphics Console device's foreground color and background color.
1732 @param This Protocol instance pointer.
1733 @param Foreground Returned text foreground color.
1734 @param Background Returned text background color.
1736 @retval EFI_SUCCESS It returned always.
1741 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1742 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Foreground
,
1743 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Background
1748 Attribute
= This
->Mode
->Attribute
& 0x7F;
1750 *Foreground
= mGraphicsEfiColors
[Attribute
& 0x0f];
1751 *Background
= mGraphicsEfiColors
[Attribute
>> 4];
1757 Draw Unicode string on the Graphics Console device's screen.
1759 @param This Protocol instance pointer.
1760 @param UnicodeWeight One Unicode string to be displayed.
1761 @param Count The count of Unicode string.
1763 @retval EFI_OUT_OF_RESOURCES If no memory resource to use.
1764 @retval EFI_UNSUPPORTED If no Graphics Output protocol and UGA Draw
1766 @retval EFI_SUCCESS Drawing Unicode string implemented successfully.
1770 DrawUnicodeWeightAtCursorN (
1771 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1772 IN CHAR16
*UnicodeWeight
,
1777 GRAPHICS_CONSOLE_DEV
*Private
;
1778 EFI_IMAGE_OUTPUT
*Blt
;
1780 EFI_FONT_DISPLAY_INFO
*FontInfo
;
1781 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1782 EFI_HII_ROW_INFO
*RowInfoArray
;
1783 UINTN RowInfoArraySize
;
1785 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1786 Blt
= (EFI_IMAGE_OUTPUT
*)AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT
));
1788 return EFI_OUT_OF_RESOURCES
;
1791 Blt
->Width
= (UINT16
)(Private
->ModeData
[This
->Mode
->Mode
].GopWidth
);
1792 Blt
->Height
= (UINT16
)(Private
->ModeData
[This
->Mode
->Mode
].GopHeight
);
1794 String
= AllocateCopyPool ((Count
+ 1) * sizeof (CHAR16
), UnicodeWeight
);
1795 if (String
== NULL
) {
1797 return EFI_OUT_OF_RESOURCES
;
1801 // Set the end character
1803 *(String
+ Count
) = L
'\0';
1805 FontInfo
= (EFI_FONT_DISPLAY_INFO
*)AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO
));
1806 if (FontInfo
== NULL
) {
1809 return EFI_OUT_OF_RESOURCES
;
1813 // Get current foreground and background colors.
1815 GetTextColors (This
, &FontInfo
->ForegroundColor
, &FontInfo
->BackgroundColor
);
1817 if (Private
->GraphicsOutput
!= NULL
) {
1819 // If Graphics Output protocol exists, using HII Font protocol to draw.
1821 Blt
->Image
.Screen
= Private
->GraphicsOutput
;
1823 Status
= mHiiFont
->StringToImage (
1825 EFI_HII_IGNORE_IF_NO_GLYPH
| EFI_HII_DIRECT_TO_SCREEN
| EFI_HII_IGNORE_LINE_BREAK
,
1829 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1830 This
->Mode
->CursorRow
* EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1835 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1837 // If Graphics Output protocol cannot be found and PcdUgaConsumeSupport enabled,
1838 // using UGA Draw protocol to draw.
1840 ASSERT (Private
->UgaDraw
!= NULL
);
1842 UgaDraw
= Private
->UgaDraw
;
1844 Blt
->Image
.Bitmap
= AllocateZeroPool (Blt
->Width
* Blt
->Height
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
1845 if (Blt
->Image
.Bitmap
== NULL
) {
1848 return EFI_OUT_OF_RESOURCES
;
1851 RowInfoArray
= NULL
;
1853 // StringToImage only support blt'ing image to device using GOP protocol. If GOP is not supported in this platform,
1854 // we ask StringToImage to print the string to blt buffer, then blt to device using UgaDraw.
1856 Status
= mHiiFont
->StringToImage (
1858 EFI_HII_IGNORE_IF_NO_GLYPH
| EFI_HII_IGNORE_LINE_BREAK
,
1862 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1863 This
->Mode
->CursorRow
* EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1869 if (!EFI_ERROR (Status
)) {
1871 // Line breaks are handled by caller of DrawUnicodeWeightAtCursorN, so the updated parameter RowInfoArraySize by StringToImage will
1872 // always be 1 or 0 (if there is no valid Unicode Char can be printed). ASSERT here to make sure.
1874 ASSERT (RowInfoArraySize
<= 1);
1876 Status
= UgaDraw
->Blt (
1878 (EFI_UGA_PIXEL
*)Blt
->Image
.Bitmap
,
1879 EfiUgaBltBufferToVideo
,
1880 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1881 (This
->Mode
->CursorRow
) * EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1882 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1883 (This
->Mode
->CursorRow
) * EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1884 RowInfoArray
[0].LineWidth
,
1885 RowInfoArray
[0].LineHeight
,
1886 Blt
->Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1890 FreePool (RowInfoArray
);
1891 FreePool (Blt
->Image
.Bitmap
);
1893 Status
= EFI_UNSUPPORTED
;
1900 if (String
!= NULL
) {
1904 if (FontInfo
!= NULL
) {
1905 FreePool (FontInfo
);
1912 Flush the cursor on the screen.
1914 If CursorVisible is FALSE, nothing to do and return directly.
1915 If CursorVisible is TRUE,
1916 i) If the cursor shows on screen, it will be erased.
1917 ii) If the cursor does not show on screen, it will be shown.
1919 @param This Protocol instance pointer.
1921 @retval EFI_SUCCESS The cursor is erased successfully.
1926 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
1929 GRAPHICS_CONSOLE_DEV
*Private
;
1930 EFI_SIMPLE_TEXT_OUTPUT_MODE
*CurrentMode
;
1933 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1934 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1935 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground
;
1936 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background
;
1937 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar
[EFI_GLYPH_HEIGHT
][EFI_GLYPH_WIDTH
];
1941 CurrentMode
= This
->Mode
;
1943 if (!CurrentMode
->CursorVisible
) {
1947 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1948 GraphicsOutput
= Private
->GraphicsOutput
;
1949 UgaDraw
= Private
->UgaDraw
;
1952 // In this driver, only narrow character was supported.
1955 // Blt a character to the screen
1957 GlyphX
= (CurrentMode
->CursorColumn
* EFI_GLYPH_WIDTH
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaX
;
1958 GlyphY
= (CurrentMode
->CursorRow
* EFI_GLYPH_HEIGHT
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaY
;
1959 if (GraphicsOutput
!= NULL
) {
1960 GraphicsOutput
->Blt (
1962 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*)BltChar
,
1963 EfiBltVideoToBltBuffer
,
1970 EFI_GLYPH_WIDTH
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1972 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1975 (EFI_UGA_PIXEL
*)(UINTN
)BltChar
,
1976 EfiUgaVideoToBltBuffer
,
1983 EFI_GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)
1987 GetTextColors (This
, &Foreground
.Pixel
, &Background
.Pixel
);
1990 // Convert Monochrome bitmap of the Glyph to BltBuffer structure
1992 for (PosY
= 0; PosY
< EFI_GLYPH_HEIGHT
; PosY
++) {
1993 for (PosX
= 0; PosX
< EFI_GLYPH_WIDTH
; PosX
++) {
1994 if ((mCursorGlyph
.GlyphCol1
[PosY
] & (BIT0
<< PosX
)) != 0) {
1995 BltChar
[PosY
][EFI_GLYPH_WIDTH
- PosX
- 1].Raw
^= Foreground
.Raw
;
2000 if (GraphicsOutput
!= NULL
) {
2001 GraphicsOutput
->Blt (
2003 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*)BltChar
,
2004 EfiBltBufferToVideo
,
2011 EFI_GLYPH_WIDTH
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
2013 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
2016 (EFI_UGA_PIXEL
*)(UINTN
)BltChar
,
2017 EfiUgaBltBufferToVideo
,
2024 EFI_GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)
2032 HII Database Protocol notification event handler.
2034 Register font package when HII Database Protocol has been installed.
2036 @param[in] Event Event whose notification function is being invoked.
2037 @param[in] Context Pointer to the notification function's context.
2041 RegisterFontPackage (
2047 EFI_HII_SIMPLE_FONT_PACKAGE_HDR
*SimplifiedFont
;
2048 UINT32 PackageLength
;
2051 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
2054 // Locate HII Database Protocol
2056 Status
= gBS
->LocateProtocol (
2057 &gEfiHiiDatabaseProtocolGuid
,
2059 (VOID
**)&HiiDatabase
2061 if (EFI_ERROR (Status
)) {
2066 // Add 4 bytes to the header for entire length for HiiAddPackages use only.
2068 // +--------------------------------+ <-- Package
2070 // | PackageLength(4 bytes) |
2072 // |--------------------------------| <-- SimplifiedFont
2074 // |EFI_HII_SIMPLE_FONT_PACKAGE_HDR |
2076 // |--------------------------------| <-- Location
2078 // | gUsStdNarrowGlyphData |
2080 // +--------------------------------+
2082 PackageLength
= sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR
) + mNarrowFontSize
+ 4;
2083 Package
= AllocateZeroPool (PackageLength
);
2084 ASSERT (Package
!= NULL
);
2086 WriteUnaligned32 ((UINT32
*)Package
, PackageLength
);
2087 SimplifiedFont
= (EFI_HII_SIMPLE_FONT_PACKAGE_HDR
*)(Package
+ 4);
2088 SimplifiedFont
->Header
.Length
= (UINT32
)(PackageLength
- 4);
2089 SimplifiedFont
->Header
.Type
= EFI_HII_PACKAGE_SIMPLE_FONTS
;
2090 SimplifiedFont
->NumberOfNarrowGlyphs
= (UINT16
)(mNarrowFontSize
/ sizeof (EFI_NARROW_GLYPH
));
2092 Location
= (UINT8
*)(&SimplifiedFont
->NumberOfWideGlyphs
+ 1);
2093 CopyMem (Location
, gUsStdNarrowGlyphData
, mNarrowFontSize
);
2096 // Add this simplified font package to a package list then install it.
2098 mHiiHandle
= HiiAddPackages (
2099 &mFontPackageListGuid
,
2104 ASSERT (mHiiHandle
!= NULL
);
2109 The user Entry Point for module GraphicsConsole. The user code starts with this function.
2111 @param[in] ImageHandle The firmware allocated handle for the EFI image.
2112 @param[in] SystemTable A pointer to the EFI System Table.
2114 @retval EFI_SUCCESS The entry point is executed successfully.
2115 @return other Some error occurs when executing this entry point.
2120 InitializeGraphicsConsole (
2121 IN EFI_HANDLE ImageHandle
,
2122 IN EFI_SYSTEM_TABLE
*SystemTable
2128 // Register notify function on HII Database Protocol to add font package.
2130 EfiCreateProtocolNotifyEvent (
2131 &gEfiHiiDatabaseProtocolGuid
,
2133 RegisterFontPackage
,
2139 // Install driver model protocol(s).
2141 Status
= EfiLibInstallDriverBindingComponentName2 (
2144 &gGraphicsConsoleDriverBinding
,
2146 &gGraphicsConsoleComponentName
,
2147 &gGraphicsConsoleComponentName2
2149 ASSERT_EFI_ERROR (Status
);