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
[] = {
43 { 100, 31 }, // 800 x 600
44 { 128, 40 }, // 1024 x 768
45 { 160, 42 }, // 1280 x 800
46 { 240, 56 }, // 1920 x 1080
48 // New modes can be added here.
49 // The last entry is specific for full screen mode.
54 EFI_HII_DATABASE_PROTOCOL
*mHiiDatabase
;
55 EFI_HII_FONT_PROTOCOL
*mHiiFont
;
56 EFI_HII_HANDLE mHiiHandle
;
57 VOID
*mHiiRegistration
;
59 EFI_GUID mFontPackageListGuid
= {
60 0xf5f219d3, 0x7006, 0x4648, { 0xac, 0x8d, 0xd6, 0x1d, 0xfb, 0x7b, 0xc6, 0xad }
63 CHAR16 mCrLfString
[3] = { CHAR_CARRIAGE_RETURN
, CHAR_LINEFEED
, CHAR_NULL
};
65 EFI_GRAPHICS_OUTPUT_BLT_PIXEL mGraphicsEfiColors
[16] = {
69 { 0x00, 0x00, 0x00, 0x00 }, // BLACK
70 { 0x98, 0x00, 0x00, 0x00 }, // LIGHTBLUE
71 { 0x00, 0x98, 0x00, 0x00 }, // LIGHGREEN
72 { 0x98, 0x98, 0x00, 0x00 }, // LIGHCYAN
73 { 0x00, 0x00, 0x98, 0x00 }, // LIGHRED
74 { 0x98, 0x00, 0x98, 0x00 }, // MAGENTA
75 { 0x00, 0x98, 0x98, 0x00 }, // BROWN
76 { 0x98, 0x98, 0x98, 0x00 }, // LIGHTGRAY
77 { 0x30, 0x30, 0x30, 0x00 }, // DARKGRAY - BRIGHT BLACK
78 { 0xff, 0x00, 0x00, 0x00 }, // BLUE
79 { 0x00, 0xff, 0x00, 0x00 }, // LIME
80 { 0xff, 0xff, 0x00, 0x00 }, // CYAN
81 { 0x00, 0x00, 0xff, 0x00 }, // RED
82 { 0xff, 0x00, 0xff, 0x00 }, // FUCHSIA
83 { 0x00, 0xff, 0xff, 0x00 }, // YELLOW
84 { 0xff, 0xff, 0xff, 0x00 } // WHITE
87 EFI_NARROW_GLYPH mCursorGlyph
= {
90 { 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF }
93 CHAR16 SpaceStr
[] = { NARROW_CHAR
, ' ', 0 };
95 EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding
= {
96 GraphicsConsoleControllerDriverSupported
,
97 GraphicsConsoleControllerDriverStart
,
98 GraphicsConsoleControllerDriverStop
,
105 Test to see if Graphics Console could be supported on the Controller.
107 Graphics Console could be supported if Graphics Output Protocol or UGA Draw
108 Protocol exists on the Controller. (UGA Draw Protocol could be skipped
109 if PcdUgaConsumeSupport is set to FALSE.)
111 @param This Protocol instance pointer.
112 @param Controller Handle of device to test.
113 @param RemainingDevicePath Optional parameter use to pick a specific child
116 @retval EFI_SUCCESS This driver supports this device.
117 @retval other This driver does not support this device.
122 GraphicsConsoleControllerDriverSupported (
123 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
124 IN EFI_HANDLE Controller
,
125 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
129 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
130 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
131 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
133 GraphicsOutput
= NULL
;
136 // Open the IO Abstraction(s) needed to perform the supported test
138 Status
= gBS
->OpenProtocol (
140 &gEfiGraphicsOutputProtocolGuid
,
141 (VOID
**)&GraphicsOutput
,
142 This
->DriverBindingHandle
,
144 EFI_OPEN_PROTOCOL_BY_DRIVER
147 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
149 // Open Graphics Output Protocol failed, try to open UGA Draw Protocol
151 Status
= gBS
->OpenProtocol (
153 &gEfiUgaDrawProtocolGuid
,
155 This
->DriverBindingHandle
,
157 EFI_OPEN_PROTOCOL_BY_DRIVER
161 if (EFI_ERROR (Status
)) {
166 // We need to ensure that we do not layer on top of a virtual handle.
167 // We need to ensure that the handles produced by the conspliter do not
170 Status
= gBS
->OpenProtocol (
172 &gEfiDevicePathProtocolGuid
,
173 (VOID
**)&DevicePath
,
174 This
->DriverBindingHandle
,
176 EFI_OPEN_PROTOCOL_BY_DRIVER
178 if (!EFI_ERROR (Status
)) {
181 &gEfiDevicePathProtocolGuid
,
182 This
->DriverBindingHandle
,
190 // Does Hii Exist? If not, we aren't ready to run
192 Status
= EfiLocateHiiProtocol ();
195 // Close the I/O Abstraction(s) used to perform the supported test
198 if (GraphicsOutput
!= NULL
) {
201 &gEfiGraphicsOutputProtocolGuid
,
202 This
->DriverBindingHandle
,
205 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
208 &gEfiUgaDrawProtocolGuid
,
209 This
->DriverBindingHandle
,
218 Initialize all the text modes which the graphics console supports.
220 It returns information for available text modes that the graphics can support.
222 @param[in] HorizontalResolution The size of video screen in pixels in the X dimension.
223 @param[in] VerticalResolution The size of video screen in pixels in the Y dimension.
224 @param[in] GopModeNumber The graphics mode number which graphics console is based on.
225 @param[out] TextModeCount The total number of text modes that graphics console supports.
226 @param[out] TextModeData The buffer to the text modes column and row information.
227 Caller is responsible to free it when it's non-NULL.
229 @retval EFI_SUCCESS The supporting mode information is returned.
230 @retval EFI_INVALID_PARAMETER The parameters are invalid.
234 InitializeGraphicsConsoleTextMode (
235 IN UINT32 HorizontalResolution
,
236 IN UINT32 VerticalResolution
,
237 IN UINT32 GopModeNumber
,
238 OUT UINTN
*TextModeCount
,
239 OUT GRAPHICS_CONSOLE_MODE_DATA
**TextModeData
244 GRAPHICS_CONSOLE_MODE_DATA
*ModeBuffer
;
245 GRAPHICS_CONSOLE_MODE_DATA
*NewModeBuffer
;
251 if ((TextModeCount
== NULL
) || (TextModeData
== NULL
)) {
252 return EFI_INVALID_PARAMETER
;
255 Count
= sizeof (mGraphicsConsoleModeData
) / sizeof (GRAPHICS_CONSOLE_MODE_DATA
);
258 // Compute the maximum number of text Rows and Columns that this current graphics mode can support.
259 // To make graphics console work well, MaxColumns and MaxRows should not be zero.
261 MaxColumns
= HorizontalResolution
/ EFI_GLYPH_WIDTH
;
262 MaxRows
= VerticalResolution
/ EFI_GLYPH_HEIGHT
;
265 // According to UEFI spec, all output devices support at least 80x25 text mode.
267 ASSERT ((MaxColumns
>= 80) && (MaxRows
>= 25));
270 // Add full screen mode to the last entry.
272 mGraphicsConsoleModeData
[Count
- 1].Columns
= MaxColumns
;
273 mGraphicsConsoleModeData
[Count
- 1].Rows
= MaxRows
;
276 // Get defined mode buffer pointer.
278 ModeBuffer
= mGraphicsConsoleModeData
;
281 // Here we make sure that the final mode exposed does not include the duplicated modes,
282 // and does not include the invalid modes which exceed the max column and row.
283 // Reserve 2 modes for 80x25, 80x50 of graphics console.
285 NewModeBuffer
= AllocateZeroPool (sizeof (GRAPHICS_CONSOLE_MODE_DATA
) * (Count
+ 2));
286 ASSERT (NewModeBuffer
!= NULL
);
289 // Mode 0 and mode 1 is for 80x25, 80x50 according to UEFI spec.
293 NewModeBuffer
[ValidCount
].Columns
= 80;
294 NewModeBuffer
[ValidCount
].Rows
= 25;
295 NewModeBuffer
[ValidCount
].GopWidth
= HorizontalResolution
;
296 NewModeBuffer
[ValidCount
].GopHeight
= VerticalResolution
;
297 NewModeBuffer
[ValidCount
].GopModeNumber
= GopModeNumber
;
298 NewModeBuffer
[ValidCount
].DeltaX
= (HorizontalResolution
- (NewModeBuffer
[ValidCount
].Columns
* EFI_GLYPH_WIDTH
)) >> 1;
299 NewModeBuffer
[ValidCount
].DeltaY
= (VerticalResolution
- (NewModeBuffer
[ValidCount
].Rows
* EFI_GLYPH_HEIGHT
)) >> 1;
302 if ((MaxColumns
>= 80) && (MaxRows
>= 50)) {
303 NewModeBuffer
[ValidCount
].Columns
= 80;
304 NewModeBuffer
[ValidCount
].Rows
= 50;
305 NewModeBuffer
[ValidCount
].DeltaX
= (HorizontalResolution
- (80 * EFI_GLYPH_WIDTH
)) >> 1;
306 NewModeBuffer
[ValidCount
].DeltaY
= (VerticalResolution
- (50 * EFI_GLYPH_HEIGHT
)) >> 1;
309 NewModeBuffer
[ValidCount
].GopWidth
= HorizontalResolution
;
310 NewModeBuffer
[ValidCount
].GopHeight
= VerticalResolution
;
311 NewModeBuffer
[ValidCount
].GopModeNumber
= GopModeNumber
;
315 // Start from mode 2 to put the valid mode other than 80x25 and 80x50 in the output mode buffer.
317 for (Index
= 0; Index
< Count
; Index
++) {
318 if ((ModeBuffer
[Index
].Columns
== 0) || (ModeBuffer
[Index
].Rows
== 0) ||
319 (ModeBuffer
[Index
].Columns
> MaxColumns
) || (ModeBuffer
[Index
].Rows
> MaxRows
))
322 // Skip the pre-defined mode which is invalid or exceeds the max column and row.
327 for (ValidIndex
= 0; ValidIndex
< ValidCount
; ValidIndex
++) {
328 if ((ModeBuffer
[Index
].Columns
== NewModeBuffer
[ValidIndex
].Columns
) &&
329 (ModeBuffer
[Index
].Rows
== NewModeBuffer
[ValidIndex
].Rows
))
332 // Skip the duplicated mode.
338 if (ValidIndex
== ValidCount
) {
339 NewModeBuffer
[ValidCount
].Columns
= ModeBuffer
[Index
].Columns
;
340 NewModeBuffer
[ValidCount
].Rows
= ModeBuffer
[Index
].Rows
;
341 NewModeBuffer
[ValidCount
].GopWidth
= HorizontalResolution
;
342 NewModeBuffer
[ValidCount
].GopHeight
= VerticalResolution
;
343 NewModeBuffer
[ValidCount
].GopModeNumber
= GopModeNumber
;
344 NewModeBuffer
[ValidCount
].DeltaX
= (HorizontalResolution
- (NewModeBuffer
[ValidCount
].Columns
* EFI_GLYPH_WIDTH
)) >> 1;
345 NewModeBuffer
[ValidCount
].DeltaY
= (VerticalResolution
- (NewModeBuffer
[ValidCount
].Rows
* EFI_GLYPH_HEIGHT
)) >> 1;
351 for (Index
= 0; Index
< ValidCount
; Index
++) {
354 "Graphics - Mode %d, Column = %d, Row = %d\n",
356 NewModeBuffer
[Index
].Columns
,
357 NewModeBuffer
[Index
].Rows
364 // Return valid mode count and mode information buffer.
366 *TextModeCount
= ValidCount
;
367 *TextModeData
= NewModeBuffer
;
372 Start this driver on Controller by opening Graphics Output protocol or
373 UGA Draw protocol, and installing Simple Text Out protocol on Controller.
374 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)
376 @param This Protocol instance pointer.
377 @param Controller Handle of device to bind driver to
378 @param RemainingDevicePath Optional parameter use to pick a specific child
381 @retval EFI_SUCCESS This driver is added to Controller.
382 @retval other This driver does not support this device.
387 GraphicsConsoleControllerDriverStart (
388 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
389 IN EFI_HANDLE Controller
,
390 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
394 GRAPHICS_CONSOLE_DEV
*Private
;
395 UINT32 HorizontalResolution
;
396 UINT32 VerticalResolution
;
402 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
*Mode
;
404 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
415 // Initialize the Graphics Console device instance
417 Private
= AllocateCopyPool (
418 sizeof (GRAPHICS_CONSOLE_DEV
),
419 &mGraphicsConsoleDevTemplate
421 if (Private
== NULL
) {
422 return EFI_OUT_OF_RESOURCES
;
425 Private
->SimpleTextOutput
.Mode
= &(Private
->SimpleTextOutputMode
);
427 Status
= gBS
->OpenProtocol (
429 &gEfiGraphicsOutputProtocolGuid
,
430 (VOID
**)&Private
->GraphicsOutput
,
431 This
->DriverBindingHandle
,
433 EFI_OPEN_PROTOCOL_BY_DRIVER
436 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
437 Status
= gBS
->OpenProtocol (
439 &gEfiUgaDrawProtocolGuid
,
440 (VOID
**)&Private
->UgaDraw
,
441 This
->DriverBindingHandle
,
443 EFI_OPEN_PROTOCOL_BY_DRIVER
447 if (EFI_ERROR (Status
)) {
451 HorizontalResolution
= PcdGet32 (PcdVideoHorizontalResolution
);
452 VerticalResolution
= PcdGet32 (PcdVideoVerticalResolution
);
454 if (Private
->GraphicsOutput
!= NULL
) {
456 // The console is build on top of Graphics Output Protocol, find the mode number
457 // for the user-defined mode; if there are multiple video devices,
458 // graphic console driver will set all the video devices to the same mode.
460 if ((HorizontalResolution
== 0x0) || (VerticalResolution
== 0x0)) {
462 // Find the highest resolution which GOP supports.
464 MaxMode
= Private
->GraphicsOutput
->Mode
->MaxMode
;
466 for (ModeIndex
= 0; ModeIndex
< MaxMode
; ModeIndex
++) {
467 Status
= Private
->GraphicsOutput
->QueryMode (
468 Private
->GraphicsOutput
,
473 if (!EFI_ERROR (Status
)) {
474 if ((Info
->HorizontalResolution
> HorizontalResolution
) ||
475 ((Info
->HorizontalResolution
== HorizontalResolution
) && (Info
->VerticalResolution
> VerticalResolution
)))
477 HorizontalResolution
= Info
->HorizontalResolution
;
478 VerticalResolution
= Info
->VerticalResolution
;
479 ModeNumber
= ModeIndex
;
486 if ((HorizontalResolution
== 0x0) || (VerticalResolution
== 0x0)) {
487 Status
= EFI_UNSUPPORTED
;
492 // Use user-defined resolution
494 Status
= CheckModeSupported (
495 Private
->GraphicsOutput
,
496 HorizontalResolution
,
500 if (EFI_ERROR (Status
)) {
502 // if not supporting current mode, try 800x600 which is required by UEFI/EFI spec
504 HorizontalResolution
= 800;
505 VerticalResolution
= 600;
506 Status
= CheckModeSupported (
507 Private
->GraphicsOutput
,
508 HorizontalResolution
,
512 Mode
= Private
->GraphicsOutput
->Mode
;
513 if (EFI_ERROR (Status
) && (Mode
->MaxMode
!= 0)) {
515 // If set default mode failed or device doesn't support default mode, then get the current mode information
517 HorizontalResolution
= Mode
->Info
->HorizontalResolution
;
518 VerticalResolution
= Mode
->Info
->VerticalResolution
;
519 ModeNumber
= Mode
->Mode
;
524 if (EFI_ERROR (Status
) || (ModeNumber
!= Private
->GraphicsOutput
->Mode
->Mode
)) {
526 // Current graphics mode is not set or is not set to the mode which we have found,
527 // set the new graphic mode.
529 Status
= Private
->GraphicsOutput
->SetMode (Private
->GraphicsOutput
, ModeNumber
);
530 if (EFI_ERROR (Status
)) {
532 // The mode set operation failed
537 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
539 // At first try to set user-defined resolution
543 Status
= Private
->UgaDraw
->SetMode (
545 HorizontalResolution
,
550 if (EFI_ERROR (Status
)) {
552 // Try to set 800*600 which is required by UEFI/EFI spec
554 Status
= Private
->UgaDraw
->SetMode (
561 if (EFI_ERROR (Status
)) {
562 Status
= Private
->UgaDraw
->GetMode (
564 &HorizontalResolution
,
569 if (EFI_ERROR (Status
)) {
576 DEBUG ((DEBUG_INFO
, "GraphicsConsole video resolution %d x %d\n", HorizontalResolution
, VerticalResolution
));
579 // Initialize the mode which GraphicsConsole supports.
581 Status
= InitializeGraphicsConsoleTextMode (
582 HorizontalResolution
,
589 if (EFI_ERROR (Status
)) {
594 // Update the maximum number of modes
596 Private
->SimpleTextOutputMode
.MaxMode
= (INT32
)MaxMode
;
599 // Initialize the Mode of graphics console devices
602 DefaultColumn
= PcdGet32 (PcdConOutColumn
);
603 DefaultRow
= PcdGet32 (PcdConOutRow
);
606 for (Index
= 0; Index
< (INT32
)MaxMode
; Index
++) {
607 if ((DefaultColumn
!= 0) && (DefaultRow
!= 0)) {
608 if ((Private
->ModeData
[Index
].Columns
== DefaultColumn
) &&
609 (Private
->ModeData
[Index
].Rows
== DefaultRow
))
615 if ((Private
->ModeData
[Index
].Columns
> Column
) &&
616 (Private
->ModeData
[Index
].Rows
> Row
))
618 Column
= Private
->ModeData
[Index
].Columns
;
619 Row
= Private
->ModeData
[Index
].Rows
;
625 Private
->SimpleTextOutput
.Mode
->Mode
= (INT32
)PreferMode
;
626 DEBUG ((DEBUG_INFO
, "Graphics Console Started, Mode: %d\n", PreferMode
));
629 // Install protocol interfaces for the Graphics Console device.
631 Status
= gBS
->InstallMultipleProtocolInterfaces (
633 &gEfiSimpleTextOutProtocolGuid
,
634 &Private
->SimpleTextOutput
,
639 if (EFI_ERROR (Status
)) {
641 // Close the GOP and UGA Draw Protocol
643 if (Private
->GraphicsOutput
!= NULL
) {
646 &gEfiGraphicsOutputProtocolGuid
,
647 This
->DriverBindingHandle
,
650 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
653 &gEfiUgaDrawProtocolGuid
,
654 This
->DriverBindingHandle
,
659 if (Private
->LineBuffer
!= NULL
) {
660 FreePool (Private
->LineBuffer
);
663 if (Private
->ModeData
!= NULL
) {
664 FreePool (Private
->ModeData
);
677 Stop this driver on Controller by removing Simple Text Out protocol
678 and closing the Graphics Output Protocol or UGA Draw protocol on Controller.
679 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)
682 @param This Protocol instance pointer.
683 @param Controller Handle of device to stop driver on
684 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
685 children is zero stop the entire bus driver.
686 @param ChildHandleBuffer List of Child Handles to Stop.
688 @retval EFI_SUCCESS This driver is removed Controller.
689 @retval EFI_NOT_STARTED Simple Text Out protocol could not be found the
691 @retval other This driver was not removed from this device.
696 GraphicsConsoleControllerDriverStop (
697 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
698 IN EFI_HANDLE Controller
,
699 IN UINTN NumberOfChildren
,
700 IN EFI_HANDLE
*ChildHandleBuffer
704 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
705 GRAPHICS_CONSOLE_DEV
*Private
;
707 Status
= gBS
->OpenProtocol (
709 &gEfiSimpleTextOutProtocolGuid
,
710 (VOID
**)&SimpleTextOutput
,
711 This
->DriverBindingHandle
,
713 EFI_OPEN_PROTOCOL_GET_PROTOCOL
715 if (EFI_ERROR (Status
)) {
716 return EFI_NOT_STARTED
;
719 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
721 Status
= gBS
->UninstallProtocolInterface (
723 &gEfiSimpleTextOutProtocolGuid
,
724 &Private
->SimpleTextOutput
727 if (!EFI_ERROR (Status
)) {
729 // Close the GOP or UGA IO Protocol
731 if (Private
->GraphicsOutput
!= NULL
) {
734 &gEfiGraphicsOutputProtocolGuid
,
735 This
->DriverBindingHandle
,
738 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
741 &gEfiUgaDrawProtocolGuid
,
742 This
->DriverBindingHandle
,
747 if (Private
->LineBuffer
!= NULL
) {
748 FreePool (Private
->LineBuffer
);
751 if (Private
->ModeData
!= NULL
) {
752 FreePool (Private
->ModeData
);
756 // Free our instance data
765 Check if the current specific mode supported the user defined resolution
766 for the Graphics Console device based on Graphics Output Protocol.
768 If yes, set the graphic device's current mode to this specific mode.
770 @param GraphicsOutput Graphics Output Protocol instance pointer.
771 @param HorizontalResolution User defined horizontal resolution
772 @param VerticalResolution User defined vertical resolution.
773 @param CurrentModeNumber Current specific mode to be check.
775 @retval EFI_SUCCESS The mode is supported.
776 @retval EFI_UNSUPPORTED The specific mode is out of range of graphics
778 @retval other The specific mode does not support user defined
779 resolution or failed to set the current mode to the
780 specific mode on graphics device.
785 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
786 IN UINT32 HorizontalResolution
,
787 IN UINT32 VerticalResolution
,
788 OUT UINT32
*CurrentModeNumber
794 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
797 Status
= EFI_SUCCESS
;
798 MaxMode
= GraphicsOutput
->Mode
->MaxMode
;
800 for (ModeNumber
= 0; ModeNumber
< MaxMode
; ModeNumber
++) {
801 Status
= GraphicsOutput
->QueryMode (
807 if (!EFI_ERROR (Status
)) {
808 if ((Info
->HorizontalResolution
== HorizontalResolution
) &&
809 (Info
->VerticalResolution
== VerticalResolution
))
811 if ((GraphicsOutput
->Mode
->Info
->HorizontalResolution
== HorizontalResolution
) &&
812 (GraphicsOutput
->Mode
->Info
->VerticalResolution
== VerticalResolution
))
815 // If video device has been set to this mode, we do not need to SetMode again
820 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeNumber
);
821 if (!EFI_ERROR (Status
)) {
832 if (ModeNumber
== GraphicsOutput
->Mode
->MaxMode
) {
833 Status
= EFI_UNSUPPORTED
;
836 *CurrentModeNumber
= ModeNumber
;
841 Locate HII Database protocol and HII Font protocol.
843 @retval EFI_SUCCESS HII Database protocol and HII Font protocol
844 are located successfully.
845 @return other Failed to locate HII Database protocol or
850 EfiLocateHiiProtocol (
856 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**)&mHiiDatabase
);
857 if (EFI_ERROR (Status
)) {
861 Status
= gBS
->LocateProtocol (&gEfiHiiFontProtocolGuid
, NULL
, (VOID
**)&mHiiFont
);
866 // Body of the STO functions
870 Reset the text output device hardware and optionally run diagnostics.
872 Implements SIMPLE_TEXT_OUTPUT.Reset().
873 If ExtendedVerification is TRUE, then perform dependent Graphics Console
874 device reset, and set display mode to mode 0.
875 If ExtendedVerification is FALSE, only set display mode to mode 0.
877 @param This Protocol instance pointer.
878 @param ExtendedVerification Indicates that the driver may perform a more
879 exhaustive verification operation of the device
882 @retval EFI_SUCCESS The text output device was reset.
883 @retval EFI_DEVICE_ERROR The text output device is not functioning correctly and
889 GraphicsConsoleConOutReset (
890 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
891 IN BOOLEAN ExtendedVerification
896 Status
= This
->SetMode (This
, 0);
897 if (EFI_ERROR (Status
)) {
901 Status
= This
->SetAttribute (This
, EFI_TEXT_ATTR (This
->Mode
->Attribute
& 0x0F, EFI_BACKGROUND_BLACK
));
906 Write a Unicode string to the output device.
908 Implements SIMPLE_TEXT_OUTPUT.OutputString().
909 The Unicode string will be converted to Glyphs and will be
910 sent to the Graphics Console.
912 @param This Protocol instance pointer.
913 @param WString The NULL-terminated Unicode string to be displayed
914 on the output device(s). All output devices must
915 also support the Unicode drawing defined in this file.
917 @retval EFI_SUCCESS The string was output to the device.
918 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output
920 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
922 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
923 characters in the Unicode string could not be
924 rendered and were skipped.
929 GraphicsConsoleConOutOutputString (
930 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
934 GRAPHICS_CONSOLE_DEV
*Private
;
935 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
936 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
945 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
946 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
951 INT32 OriginAttribute
;
954 if (This
->Mode
->Mode
== -1) {
956 // If current mode is not valid, return error.
958 return EFI_UNSUPPORTED
;
961 Status
= EFI_SUCCESS
;
963 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
967 Mode
= This
->Mode
->Mode
;
968 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
969 GraphicsOutput
= Private
->GraphicsOutput
;
970 UgaDraw
= Private
->UgaDraw
;
972 MaxColumn
= Private
->ModeData
[Mode
].Columns
;
973 MaxRow
= Private
->ModeData
[Mode
].Rows
;
974 DeltaX
= (UINTN
)Private
->ModeData
[Mode
].DeltaX
;
975 DeltaY
= (UINTN
)Private
->ModeData
[Mode
].DeltaY
;
976 Width
= MaxColumn
* EFI_GLYPH_WIDTH
;
977 Height
= (MaxRow
- 1) * EFI_GLYPH_HEIGHT
;
978 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
981 // The Attributes won't change when during the time OutputString is called
983 GetTextColors (This
, &Foreground
, &Background
);
992 OriginAttribute
= This
->Mode
->Attribute
;
994 while (*WString
!= L
'\0') {
995 if (*WString
== CHAR_BACKSPACE
) {
997 // If the cursor is at the left edge of the display, then move the cursor
1000 if ((This
->Mode
->CursorColumn
== 0) && (This
->Mode
->CursorRow
> 0)) {
1001 This
->Mode
->CursorRow
--;
1002 This
->Mode
->CursorColumn
= (INT32
)(MaxColumn
- 1);
1003 This
->OutputString (This
, SpaceStr
);
1005 This
->Mode
->CursorRow
--;
1006 This
->Mode
->CursorColumn
= (INT32
)(MaxColumn
- 1);
1007 } else if (This
->Mode
->CursorColumn
> 0) {
1009 // If the cursor is not at the left edge of the display, then move the cursor
1012 This
->Mode
->CursorColumn
--;
1013 This
->OutputString (This
, SpaceStr
);
1015 This
->Mode
->CursorColumn
--;
1019 } else if (*WString
== CHAR_LINEFEED
) {
1021 // If the cursor is at the bottom of the display, then scroll the display one
1022 // row, and do not update the cursor position. Otherwise, move the cursor
1025 if (This
->Mode
->CursorRow
== (INT32
)(MaxRow
- 1)) {
1026 if (GraphicsOutput
!= NULL
) {
1028 // Scroll Screen Up One Row
1030 GraphicsOutput
->Blt (
1035 DeltaY
+ EFI_GLYPH_HEIGHT
,
1044 // Print Blank Line at last line
1046 GraphicsOutput
->Blt (
1058 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1060 // Scroll Screen Up One Row
1067 DeltaY
+ EFI_GLYPH_HEIGHT
,
1076 // Print Blank Line at last line
1080 (EFI_UGA_PIXEL
*)(UINTN
)&Background
,
1092 This
->Mode
->CursorRow
++;
1096 } else if (*WString
== CHAR_CARRIAGE_RETURN
) {
1098 // Move the cursor to the beginning of the current row.
1100 This
->Mode
->CursorColumn
= 0;
1102 } else if (*WString
== WIDE_CHAR
) {
1103 This
->Mode
->Attribute
|= EFI_WIDE_ATTRIBUTE
;
1105 } else if (*WString
== NARROW_CHAR
) {
1106 This
->Mode
->Attribute
&= (~(UINT32
)EFI_WIDE_ATTRIBUTE
);
1110 // Print the character at the current cursor position and move the cursor
1111 // right one column. If this moves the cursor past the right edge of the
1112 // display, then the line should wrap to the beginning of the next line. This
1113 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the
1114 // bottom of the display, and the line wraps, then the display will be scrolled
1116 // If wide char is going to be displayed, need to display one character at a time
1117 // Or, need to know the display length of a certain string.
1119 // Index is used to determine how many character width units (wide = 2, narrow = 1)
1120 // Count is used to determine how many characters are used regardless of their attributes
1122 for (Count
= 0, Index
= 0; (This
->Mode
->CursorColumn
+ Index
) < MaxColumn
; Count
++, Index
++) {
1123 if ((WString
[Count
] == CHAR_NULL
) ||
1124 (WString
[Count
] == CHAR_BACKSPACE
) ||
1125 (WString
[Count
] == CHAR_LINEFEED
) ||
1126 (WString
[Count
] == CHAR_CARRIAGE_RETURN
) ||
1127 (WString
[Count
] == WIDE_CHAR
) ||
1128 (WString
[Count
] == NARROW_CHAR
))
1134 // Is the wide attribute on?
1136 if ((This
->Mode
->Attribute
& EFI_WIDE_ATTRIBUTE
) != 0) {
1138 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop
1142 // This is the end-case where if we are at column 79 and about to print a wide character
1143 // We should prevent this from happening because we will wrap inappropriately. We should
1144 // not print this character until the next line.
1146 if ((This
->Mode
->CursorColumn
+ Index
+ 1) > MaxColumn
) {
1153 Status
= DrawUnicodeWeightAtCursorN (This
, WString
, Count
);
1154 if (EFI_ERROR (Status
)) {
1159 // At the end of line, output carriage return and line feed
1162 This
->Mode
->CursorColumn
+= (INT32
)Index
;
1163 if (This
->Mode
->CursorColumn
> (INT32
)MaxColumn
) {
1164 This
->Mode
->CursorColumn
-= 2;
1165 This
->OutputString (This
, SpaceStr
);
1168 if (This
->Mode
->CursorColumn
>= (INT32
)MaxColumn
) {
1170 This
->OutputString (This
, mCrLfString
);
1176 This
->Mode
->Attribute
= OriginAttribute
;
1181 Status
= EFI_WARN_UNKNOWN_GLYPH
;
1184 gBS
->RestoreTPL (OldTpl
);
1189 Verifies that all characters in a Unicode string can be output to the
1192 Implements SIMPLE_TEXT_OUTPUT.TestString().
1193 If one of the characters in the *Wstring is neither valid valid Unicode
1194 drawing characters, not ASCII code, then this function will return
1197 @param This Protocol instance pointer.
1198 @param WString The NULL-terminated Unicode string to be examined for the output
1201 @retval EFI_SUCCESS The device(s) are capable of rendering the output string.
1202 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be
1203 rendered by one or more of the output devices mapped
1209 GraphicsConsoleConOutTestString (
1210 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1217 EFI_IMAGE_OUTPUT
*Blt
;
1222 while (WString
[Count
] != 0) {
1223 Status
= mHiiFont
->GetGlyph (
1237 if (EFI_ERROR (Status
)) {
1238 return EFI_UNSUPPORTED
;
1246 Returns information for an available text mode that the output device(s)
1249 Implements SIMPLE_TEXT_OUTPUT.QueryMode().
1250 It returnes information for an available text mode that the Graphics Console supports.
1251 In this driver,we only support text mode 80x25, which is defined as mode 0.
1253 @param This Protocol instance pointer.
1254 @param ModeNumber The mode number to return information on.
1255 @param Columns The returned columns of the requested mode.
1256 @param Rows The returned rows of the requested mode.
1258 @retval EFI_SUCCESS The requested mode information is returned.
1259 @retval EFI_UNSUPPORTED The mode number is not valid.
1264 GraphicsConsoleConOutQueryMode (
1265 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1266 IN UINTN ModeNumber
,
1271 GRAPHICS_CONSOLE_DEV
*Private
;
1275 if (ModeNumber
>= (UINTN
)This
->Mode
->MaxMode
) {
1276 return EFI_UNSUPPORTED
;
1279 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1280 Status
= EFI_SUCCESS
;
1282 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1284 *Columns
= Private
->ModeData
[ModeNumber
].Columns
;
1285 *Rows
= Private
->ModeData
[ModeNumber
].Rows
;
1287 if ((*Columns
<= 0) || (*Rows
<= 0)) {
1288 Status
= EFI_UNSUPPORTED
;
1293 gBS
->RestoreTPL (OldTpl
);
1298 Sets the output device(s) to a specified mode.
1300 Implements SIMPLE_TEXT_OUTPUT.SetMode().
1301 Set the Graphics Console to a specified mode. In this driver, we only support mode 0.
1303 @param This Protocol instance pointer.
1304 @param ModeNumber The text mode to set.
1306 @retval EFI_SUCCESS The requested text mode is set.
1307 @retval EFI_DEVICE_ERROR The requested text mode cannot be set because of
1308 Graphics Console device error.
1309 @retval EFI_UNSUPPORTED The text mode number is not valid.
1314 GraphicsConsoleConOutSetMode (
1315 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1320 GRAPHICS_CONSOLE_DEV
*Private
;
1321 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1322 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*NewLineBuffer
;
1323 UINT32 HorizontalResolution
;
1324 UINT32 VerticalResolution
;
1325 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1326 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1331 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1333 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1334 GraphicsOutput
= Private
->GraphicsOutput
;
1335 UgaDraw
= Private
->UgaDraw
;
1338 // Make sure the requested mode number is supported
1340 if (ModeNumber
>= (UINTN
)This
->Mode
->MaxMode
) {
1341 Status
= EFI_UNSUPPORTED
;
1345 ModeData
= &(Private
->ModeData
[ModeNumber
]);
1347 if ((ModeData
->Columns
<= 0) && (ModeData
->Rows
<= 0)) {
1348 Status
= EFI_UNSUPPORTED
;
1353 // If the mode has been set at least one other time, then LineBuffer will not be NULL
1355 if (Private
->LineBuffer
!= NULL
) {
1357 // If the new mode is the same as the old mode, then just return EFI_SUCCESS
1359 if ((INT32
)ModeNumber
== This
->Mode
->Mode
) {
1361 // Clear the current text window on the current graphics console
1363 This
->ClearScreen (This
);
1364 Status
= EFI_SUCCESS
;
1369 // Otherwise, the size of the text console and/or the GOP/UGA mode will be changed,
1370 // so erase the cursor, and free the LineBuffer for the current mode
1374 FreePool (Private
->LineBuffer
);
1378 // Attempt to allocate a line buffer for the requested mode number
1380 NewLineBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * ModeData
->Columns
* EFI_GLYPH_WIDTH
* EFI_GLYPH_HEIGHT
);
1382 if (NewLineBuffer
== NULL
) {
1384 // The new line buffer could not be allocated, so return an error.
1385 // No changes to the state of the current console have been made, so the current console is still valid
1387 Status
= EFI_OUT_OF_RESOURCES
;
1392 // Assign the current line buffer to the newly allocated line buffer
1394 Private
->LineBuffer
= NewLineBuffer
;
1396 if (GraphicsOutput
!= NULL
) {
1397 if (ModeData
->GopModeNumber
!= GraphicsOutput
->Mode
->Mode
) {
1399 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
1401 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeData
->GopModeNumber
);
1402 if (EFI_ERROR (Status
)) {
1404 // The mode set operation failed
1410 // The current graphics mode is correct, so simply clear the entire display
1412 Status
= GraphicsOutput
->Blt (
1414 &mGraphicsEfiColors
[0],
1421 ModeData
->GopHeight
,
1425 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1427 // Get the current UGA Draw mode information
1429 Status
= UgaDraw
->GetMode (
1431 &HorizontalResolution
,
1432 &VerticalResolution
,
1436 if (EFI_ERROR (Status
) || (HorizontalResolution
!= ModeData
->GopWidth
) || (VerticalResolution
!= ModeData
->GopHeight
)) {
1438 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
1440 Status
= UgaDraw
->SetMode (
1443 ModeData
->GopHeight
,
1447 if (EFI_ERROR (Status
)) {
1449 // The mode set operation failed
1455 // The current graphics mode is correct, so simply clear the entire display
1457 Status
= UgaDraw
->Blt (
1459 (EFI_UGA_PIXEL
*)(UINTN
)&mGraphicsEfiColors
[0],
1466 ModeData
->GopHeight
,
1473 // The new mode is valid, so commit the mode change
1475 This
->Mode
->Mode
= (INT32
)ModeNumber
;
1478 // Move the text cursor to the upper left hand corner of the display and flush it
1480 This
->Mode
->CursorColumn
= 0;
1481 This
->Mode
->CursorRow
= 0;
1485 Status
= EFI_SUCCESS
;
1488 gBS
->RestoreTPL (OldTpl
);
1493 Sets the background and foreground colors for the OutputString () and
1494 ClearScreen () functions.
1496 Implements SIMPLE_TEXT_OUTPUT.SetAttribute().
1498 @param This Protocol instance pointer.
1499 @param Attribute The attribute to set. Bits 0..3 are the foreground
1500 color, and bits 4..6 are the background color.
1501 All other bits are undefined and must be zero.
1503 @retval EFI_SUCCESS The requested attribute is set.
1504 @retval EFI_DEVICE_ERROR The requested attribute cannot be set due to Graphics Console port error.
1505 @retval EFI_UNSUPPORTED The attribute requested is not defined.
1510 GraphicsConsoleConOutSetAttribute (
1511 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1517 if ((Attribute
| 0x7F) != 0x7F) {
1518 return EFI_UNSUPPORTED
;
1521 if ((INT32
)Attribute
== This
->Mode
->Attribute
) {
1525 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1529 This
->Mode
->Attribute
= (INT32
)Attribute
;
1533 gBS
->RestoreTPL (OldTpl
);
1539 Clears the output device(s) display to the currently selected background
1542 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().
1544 @param This Protocol instance pointer.
1546 @retval EFI_SUCCESS The operation completed successfully.
1547 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
1548 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
1553 GraphicsConsoleConOutClearScreen (
1554 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
1558 GRAPHICS_CONSOLE_DEV
*Private
;
1559 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1560 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1561 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1562 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
1563 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
1566 if (This
->Mode
->Mode
== -1) {
1568 // If current mode is not valid, return error.
1570 return EFI_UNSUPPORTED
;
1573 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1575 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1576 GraphicsOutput
= Private
->GraphicsOutput
;
1577 UgaDraw
= Private
->UgaDraw
;
1578 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1580 GetTextColors (This
, &Foreground
, &Background
);
1581 if (GraphicsOutput
!= NULL
) {
1582 Status
= GraphicsOutput
->Blt (
1591 ModeData
->GopHeight
,
1594 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1595 Status
= UgaDraw
->Blt (
1597 (EFI_UGA_PIXEL
*)(UINTN
)&Background
,
1604 ModeData
->GopHeight
,
1608 Status
= EFI_UNSUPPORTED
;
1611 This
->Mode
->CursorColumn
= 0;
1612 This
->Mode
->CursorRow
= 0;
1616 gBS
->RestoreTPL (OldTpl
);
1622 Sets the current coordinates of the cursor position.
1624 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().
1626 @param This Protocol instance pointer.
1627 @param Column 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
1630 @param Row The position to set the cursor to. Must be greater than or
1631 equal to zero and less than the number of columns and rows
1634 @retval EFI_SUCCESS The operation completed successfully.
1635 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
1636 @retval EFI_UNSUPPORTED The output device is not in a valid text mode, or the
1637 cursor position is invalid for the current mode.
1642 GraphicsConsoleConOutSetCursorPosition (
1643 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1648 GRAPHICS_CONSOLE_DEV
*Private
;
1649 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1653 if (This
->Mode
->Mode
== -1) {
1655 // If current mode is not valid, return error.
1657 return EFI_UNSUPPORTED
;
1660 Status
= EFI_SUCCESS
;
1662 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1664 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1665 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1667 if ((Column
>= ModeData
->Columns
) || (Row
>= ModeData
->Rows
)) {
1668 Status
= EFI_UNSUPPORTED
;
1672 if ((This
->Mode
->CursorColumn
== (INT32
)Column
) && (This
->Mode
->CursorRow
== (INT32
)Row
)) {
1673 Status
= EFI_SUCCESS
;
1679 This
->Mode
->CursorColumn
= (INT32
)Column
;
1680 This
->Mode
->CursorRow
= (INT32
)Row
;
1685 gBS
->RestoreTPL (OldTpl
);
1691 Makes the cursor visible or invisible.
1693 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
1695 @param This Protocol instance pointer.
1696 @param Visible If TRUE, the cursor is set to be visible, If FALSE,
1697 the cursor is set to be invisible.
1699 @retval EFI_SUCCESS The operation completed successfully.
1700 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
1706 GraphicsConsoleConOutEnableCursor (
1707 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1713 if (This
->Mode
->Mode
== -1) {
1715 // If current mode is not valid, return error.
1717 return EFI_UNSUPPORTED
;
1720 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1724 This
->Mode
->CursorVisible
= Visible
;
1728 gBS
->RestoreTPL (OldTpl
);
1733 Gets Graphics Console device's foreground color and background color.
1735 @param This Protocol instance pointer.
1736 @param Foreground Returned text foreground color.
1737 @param Background Returned text background color.
1739 @retval EFI_SUCCESS It returned always.
1744 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1745 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Foreground
,
1746 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Background
1751 Attribute
= This
->Mode
->Attribute
& 0x7F;
1753 *Foreground
= mGraphicsEfiColors
[Attribute
& 0x0f];
1754 *Background
= mGraphicsEfiColors
[Attribute
>> 4];
1760 Draw Unicode string on the Graphics Console device's screen.
1762 @param This Protocol instance pointer.
1763 @param UnicodeWeight One Unicode string to be displayed.
1764 @param Count The count of Unicode string.
1766 @retval EFI_OUT_OF_RESOURCES If no memory resource to use.
1767 @retval EFI_UNSUPPORTED If no Graphics Output protocol and UGA Draw
1769 @retval EFI_SUCCESS Drawing Unicode string implemented successfully.
1773 DrawUnicodeWeightAtCursorN (
1774 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1775 IN CHAR16
*UnicodeWeight
,
1780 GRAPHICS_CONSOLE_DEV
*Private
;
1781 EFI_IMAGE_OUTPUT
*Blt
;
1783 EFI_FONT_DISPLAY_INFO
*FontInfo
;
1784 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1785 EFI_HII_ROW_INFO
*RowInfoArray
;
1786 UINTN RowInfoArraySize
;
1788 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1789 Blt
= (EFI_IMAGE_OUTPUT
*)AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT
));
1791 return EFI_OUT_OF_RESOURCES
;
1794 Blt
->Width
= (UINT16
)(Private
->ModeData
[This
->Mode
->Mode
].GopWidth
);
1795 Blt
->Height
= (UINT16
)(Private
->ModeData
[This
->Mode
->Mode
].GopHeight
);
1797 String
= AllocateCopyPool ((Count
+ 1) * sizeof (CHAR16
), UnicodeWeight
);
1798 if (String
== NULL
) {
1800 return EFI_OUT_OF_RESOURCES
;
1804 // Set the end character
1806 *(String
+ Count
) = L
'\0';
1808 FontInfo
= (EFI_FONT_DISPLAY_INFO
*)AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO
));
1809 if (FontInfo
== NULL
) {
1812 return EFI_OUT_OF_RESOURCES
;
1816 // Get current foreground and background colors.
1818 GetTextColors (This
, &FontInfo
->ForegroundColor
, &FontInfo
->BackgroundColor
);
1820 if (Private
->GraphicsOutput
!= NULL
) {
1822 // If Graphics Output protocol exists, using HII Font protocol to draw.
1824 Blt
->Image
.Screen
= Private
->GraphicsOutput
;
1826 Status
= mHiiFont
->StringToImage (
1828 EFI_HII_IGNORE_IF_NO_GLYPH
| EFI_HII_DIRECT_TO_SCREEN
| EFI_HII_IGNORE_LINE_BREAK
,
1832 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1833 This
->Mode
->CursorRow
* EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1838 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1840 // If Graphics Output protocol cannot be found and PcdUgaConsumeSupport enabled,
1841 // using UGA Draw protocol to draw.
1843 ASSERT (Private
->UgaDraw
!= NULL
);
1845 UgaDraw
= Private
->UgaDraw
;
1847 Blt
->Image
.Bitmap
= AllocateZeroPool (Blt
->Width
* Blt
->Height
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
1848 if (Blt
->Image
.Bitmap
== NULL
) {
1851 return EFI_OUT_OF_RESOURCES
;
1854 RowInfoArray
= NULL
;
1856 // StringToImage only support blt'ing image to device using GOP protocol. If GOP is not supported in this platform,
1857 // we ask StringToImage to print the string to blt buffer, then blt to device using UgaDraw.
1859 Status
= mHiiFont
->StringToImage (
1861 EFI_HII_IGNORE_IF_NO_GLYPH
| EFI_HII_IGNORE_LINE_BREAK
,
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
,
1872 if (!EFI_ERROR (Status
)) {
1874 // Line breaks are handled by caller of DrawUnicodeWeightAtCursorN, so the updated parameter RowInfoArraySize by StringToImage will
1875 // always be 1 or 0 (if there is no valid Unicode Char can be printed). ASSERT here to make sure.
1877 ASSERT (RowInfoArraySize
<= 1);
1879 Status
= UgaDraw
->Blt (
1881 (EFI_UGA_PIXEL
*)Blt
->Image
.Bitmap
,
1882 EfiUgaBltBufferToVideo
,
1883 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1884 (This
->Mode
->CursorRow
) * EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1885 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1886 (This
->Mode
->CursorRow
) * EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1887 RowInfoArray
[0].LineWidth
,
1888 RowInfoArray
[0].LineHeight
,
1889 Blt
->Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1893 FreePool (RowInfoArray
);
1894 FreePool (Blt
->Image
.Bitmap
);
1896 Status
= EFI_UNSUPPORTED
;
1903 if (String
!= NULL
) {
1907 if (FontInfo
!= NULL
) {
1908 FreePool (FontInfo
);
1915 Flush the cursor on the screen.
1917 If CursorVisible is FALSE, nothing to do and return directly.
1918 If CursorVisible is TRUE,
1919 i) If the cursor shows on screen, it will be erased.
1920 ii) If the cursor does not show on screen, it will be shown.
1922 @param This Protocol instance pointer.
1924 @retval EFI_SUCCESS The cursor is erased successfully.
1929 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
1932 GRAPHICS_CONSOLE_DEV
*Private
;
1933 EFI_SIMPLE_TEXT_OUTPUT_MODE
*CurrentMode
;
1936 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1937 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1938 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground
;
1939 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background
;
1940 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar
[EFI_GLYPH_HEIGHT
][EFI_GLYPH_WIDTH
];
1944 CurrentMode
= This
->Mode
;
1946 if (!CurrentMode
->CursorVisible
) {
1950 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1951 GraphicsOutput
= Private
->GraphicsOutput
;
1952 UgaDraw
= Private
->UgaDraw
;
1955 // In this driver, only narrow character was supported.
1958 // Blt a character to the screen
1960 GlyphX
= (CurrentMode
->CursorColumn
* EFI_GLYPH_WIDTH
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaX
;
1961 GlyphY
= (CurrentMode
->CursorRow
* EFI_GLYPH_HEIGHT
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaY
;
1962 if (GraphicsOutput
!= NULL
) {
1963 GraphicsOutput
->Blt (
1965 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*)BltChar
,
1966 EfiBltVideoToBltBuffer
,
1973 EFI_GLYPH_WIDTH
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1975 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1978 (EFI_UGA_PIXEL
*)(UINTN
)BltChar
,
1979 EfiUgaVideoToBltBuffer
,
1986 EFI_GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)
1990 GetTextColors (This
, &Foreground
.Pixel
, &Background
.Pixel
);
1993 // Convert Monochrome bitmap of the Glyph to BltBuffer structure
1995 for (PosY
= 0; PosY
< EFI_GLYPH_HEIGHT
; PosY
++) {
1996 for (PosX
= 0; PosX
< EFI_GLYPH_WIDTH
; PosX
++) {
1997 if ((mCursorGlyph
.GlyphCol1
[PosY
] & (BIT0
<< PosX
)) != 0) {
1998 BltChar
[PosY
][EFI_GLYPH_WIDTH
- PosX
- 1].Raw
^= Foreground
.Raw
;
2003 if (GraphicsOutput
!= NULL
) {
2004 GraphicsOutput
->Blt (
2006 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*)BltChar
,
2007 EfiBltBufferToVideo
,
2014 EFI_GLYPH_WIDTH
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
2016 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
2019 (EFI_UGA_PIXEL
*)(UINTN
)BltChar
,
2020 EfiUgaBltBufferToVideo
,
2027 EFI_GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)
2035 HII Database Protocol notification event handler.
2037 Register font package when HII Database Protocol has been installed.
2039 @param[in] Event Event whose notification function is being invoked.
2040 @param[in] Context Pointer to the notification function's context.
2044 RegisterFontPackage (
2050 EFI_HII_SIMPLE_FONT_PACKAGE_HDR
*SimplifiedFont
;
2051 UINT32 PackageLength
;
2054 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
2057 // Locate HII Database Protocol
2059 Status
= gBS
->LocateProtocol (
2060 &gEfiHiiDatabaseProtocolGuid
,
2062 (VOID
**)&HiiDatabase
2064 if (EFI_ERROR (Status
)) {
2069 // Add 4 bytes to the header for entire length for HiiAddPackages use only.
2071 // +--------------------------------+ <-- Package
2073 // | PackageLength(4 bytes) |
2075 // |--------------------------------| <-- SimplifiedFont
2077 // |EFI_HII_SIMPLE_FONT_PACKAGE_HDR |
2079 // |--------------------------------| <-- Location
2081 // | gUsStdNarrowGlyphData |
2083 // +--------------------------------+
2085 PackageLength
= sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR
) + mNarrowFontSize
+ 4;
2086 Package
= AllocateZeroPool (PackageLength
);
2087 ASSERT (Package
!= NULL
);
2089 WriteUnaligned32 ((UINT32
*)Package
, PackageLength
);
2090 SimplifiedFont
= (EFI_HII_SIMPLE_FONT_PACKAGE_HDR
*)(Package
+ 4);
2091 SimplifiedFont
->Header
.Length
= (UINT32
)(PackageLength
- 4);
2092 SimplifiedFont
->Header
.Type
= EFI_HII_PACKAGE_SIMPLE_FONTS
;
2093 SimplifiedFont
->NumberOfNarrowGlyphs
= (UINT16
)(mNarrowFontSize
/ sizeof (EFI_NARROW_GLYPH
));
2095 Location
= (UINT8
*)(&SimplifiedFont
->NumberOfWideGlyphs
+ 1);
2096 CopyMem (Location
, gUsStdNarrowGlyphData
, mNarrowFontSize
);
2099 // Add this simplified font package to a package list then install it.
2101 mHiiHandle
= HiiAddPackages (
2102 &mFontPackageListGuid
,
2107 ASSERT (mHiiHandle
!= NULL
);
2112 The user Entry Point for module GraphicsConsole. The user code starts with this function.
2114 @param[in] ImageHandle The firmware allocated handle for the EFI image.
2115 @param[in] SystemTable A pointer to the EFI System Table.
2117 @retval EFI_SUCCESS The entry point is executed successfully.
2118 @return other Some error occurs when executing this entry point.
2123 InitializeGraphicsConsole (
2124 IN EFI_HANDLE ImageHandle
,
2125 IN EFI_SYSTEM_TABLE
*SystemTable
2131 // Register notify function on HII Database Protocol to add font package.
2133 EfiCreateProtocolNotifyEvent (
2134 &gEfiHiiDatabaseProtocolGuid
,
2136 RegisterFontPackage
,
2142 // Install driver model protocol(s).
2144 Status
= EfiLibInstallDriverBindingComponentName2 (
2147 &gGraphicsConsoleDriverBinding
,
2149 &gGraphicsConsoleComponentName
,
2150 &gGraphicsConsoleComponentName2
2152 ASSERT_EFI_ERROR (Status
);