2 This is the main routine for initializing the Graphics Console support routines.
4 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "GraphicsConsole.h"
18 // Graphics Console Device Private Data template
20 GRAPHICS_CONSOLE_DEV mGraphicsConsoleDevTemplate
= {
21 GRAPHICS_CONSOLE_DEV_SIGNATURE
,
22 (EFI_GRAPHICS_OUTPUT_PROTOCOL
*) NULL
,
23 (EFI_UGA_DRAW_PROTOCOL
*) NULL
,
25 GraphicsConsoleConOutReset
,
26 GraphicsConsoleConOutOutputString
,
27 GraphicsConsoleConOutTestString
,
28 GraphicsConsoleConOutQueryMode
,
29 GraphicsConsoleConOutSetMode
,
30 GraphicsConsoleConOutSetAttribute
,
31 GraphicsConsoleConOutClearScreen
,
32 GraphicsConsoleConOutSetCursorPosition
,
33 GraphicsConsoleConOutEnableCursor
,
34 (EFI_SIMPLE_TEXT_OUTPUT_MODE
*) NULL
39 EFI_TEXT_ATTR(EFI_LIGHTGRAY
, EFI_BLACK
),
44 (GRAPHICS_CONSOLE_MODE_DATA
*) NULL
,
45 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) NULL
48 GRAPHICS_CONSOLE_MODE_DATA mGraphicsConsoleModeData
[] = {
51 // New modes can be added here.
52 // The last entry is specific for full screen mode.
57 EFI_HII_DATABASE_PROTOCOL
*mHiiDatabase
;
58 EFI_HII_FONT_PROTOCOL
*mHiiFont
;
59 EFI_HII_HANDLE mHiiHandle
;
60 VOID
*mHiiRegistration
;
62 EFI_GUID mFontPackageListGuid
= {0xf5f219d3, 0x7006, 0x4648, {0xac, 0x8d, 0xd6, 0x1d, 0xfb, 0x7b, 0xc6, 0xad}};
64 CHAR16 mCrLfString
[3] = { CHAR_CARRIAGE_RETURN
, CHAR_LINEFEED
, CHAR_NULL
};
66 EFI_GRAPHICS_OUTPUT_BLT_PIXEL mGraphicsEfiColors
[16] = {
70 {0x00, 0x00, 0x00, 0x00}, // BLACK
71 {0x98, 0x00, 0x00, 0x00}, // LIGHTBLUE
72 {0x00, 0x98, 0x00, 0x00}, // LIGHGREEN
73 {0x98, 0x98, 0x00, 0x00}, // LIGHCYAN
74 {0x00, 0x00, 0x98, 0x00}, // LIGHRED
75 {0x98, 0x00, 0x98, 0x00}, // MAGENTA
76 {0x00, 0x98, 0x98, 0x00}, // BROWN
77 {0x98, 0x98, 0x98, 0x00}, // LIGHTGRAY
78 {0x30, 0x30, 0x30, 0x00}, // DARKGRAY - BRIGHT BLACK
79 {0xff, 0x00, 0x00, 0x00}, // BLUE
80 {0x00, 0xff, 0x00, 0x00}, // LIME
81 {0xff, 0xff, 0x00, 0x00}, // CYAN
82 {0x00, 0x00, 0xff, 0x00}, // RED
83 {0xff, 0x00, 0xff, 0x00}, // FUCHSIA
84 {0x00, 0xff, 0xff, 0x00}, // YELLOW
85 {0xff, 0xff, 0xff, 0x00} // WHITE
88 EFI_NARROW_GLYPH mCursorGlyph
= {
91 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF }
94 CHAR16 SpaceStr
[] = { NARROW_CHAR
, ' ', 0 };
96 EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding
= {
97 GraphicsConsoleControllerDriverSupported
,
98 GraphicsConsoleControllerDriverStart
,
99 GraphicsConsoleControllerDriverStop
,
106 Test to see if Graphics Console could be supported on the Controller.
108 Graphics Console could be supported if Graphics Output Protocol or UGA Draw
109 Protocol exists on the Controller. (UGA Draw Protocol could be skipped
110 if PcdUgaConsumeSupport is set to FALSE.)
112 @param This Protocol instance pointer.
113 @param Controller Handle of device to test.
114 @param RemainingDevicePath Optional parameter use to pick a specific child
117 @retval EFI_SUCCESS This driver supports this device.
118 @retval other This driver does not support this device.
123 GraphicsConsoleControllerDriverSupported (
124 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
125 IN EFI_HANDLE Controller
,
126 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
130 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
131 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
132 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
134 GraphicsOutput
= NULL
;
137 // Open the IO Abstraction(s) needed to perform the supported test
139 Status
= gBS
->OpenProtocol (
141 &gEfiGraphicsOutputProtocolGuid
,
142 (VOID
**) &GraphicsOutput
,
143 This
->DriverBindingHandle
,
145 EFI_OPEN_PROTOCOL_BY_DRIVER
148 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
150 // Open Graphics Output Protocol failed, try to open UGA Draw Protocol
152 Status
= gBS
->OpenProtocol (
154 &gEfiUgaDrawProtocolGuid
,
156 This
->DriverBindingHandle
,
158 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
,
217 Initialize all the text modes which the graphics console supports.
219 It returns information for available text modes that the graphics can support.
221 @param[in] HorizontalResolution The size of video screen in pixels in the X dimension.
222 @param[in] VerticalResolution The size of video screen in pixels in the Y dimension.
223 @param[in] GopModeNumber The graphics mode number which graphis console is based on.
224 @param[out] TextModeCount The total number of text modes that graphics console supports.
225 @param[out] TextModeData The buffer to the text modes column and row information.
226 Caller is responsible to free it when it's non-NULL.
228 @retval EFI_SUCCESS The supporting mode information is returned.
229 @retval EFI_INVALID_PARAMETER The parameters are invalid.
233 InitializeGraphicsConsoleTextMode (
234 IN UINT32 HorizontalResolution
,
235 IN UINT32 VerticalResolution
,
236 IN UINT32 GopModeNumber
,
237 OUT UINTN
*TextModeCount
,
238 OUT GRAPHICS_CONSOLE_MODE_DATA
**TextModeData
243 GRAPHICS_CONSOLE_MODE_DATA
*ModeBuffer
;
244 GRAPHICS_CONSOLE_MODE_DATA
*NewModeBuffer
;
250 if ((TextModeCount
== NULL
) || (TextModeData
== NULL
)) {
251 return EFI_INVALID_PARAMETER
;
254 Count
= sizeof (mGraphicsConsoleModeData
) / sizeof (GRAPHICS_CONSOLE_MODE_DATA
);
257 // Compute the maximum number of text Rows and Columns that this current graphics mode can support.
258 // To make graphics console work well, MaxColumns and MaxRows should not be zero.
260 MaxColumns
= HorizontalResolution
/ EFI_GLYPH_WIDTH
;
261 MaxRows
= VerticalResolution
/ EFI_GLYPH_HEIGHT
;
264 // According to UEFI spec, all output devices support at least 80x25 text mode.
266 ASSERT ((MaxColumns
>= 80) && (MaxRows
>= 25));
269 // Add full screen mode to the last entry.
271 mGraphicsConsoleModeData
[Count
- 1].Columns
= MaxColumns
;
272 mGraphicsConsoleModeData
[Count
- 1].Rows
= MaxRows
;
275 // Get defined mode buffer pointer.
277 ModeBuffer
= mGraphicsConsoleModeData
;
280 // Here we make sure that the final mode exposed does not include the duplicated modes,
281 // and does not include the invalid modes which exceed the max column and row.
282 // Reserve 2 modes for 80x25, 80x50 of graphics console.
284 NewModeBuffer
= AllocateZeroPool (sizeof (GRAPHICS_CONSOLE_MODE_DATA
) * (Count
+ 2));
285 ASSERT (NewModeBuffer
!= NULL
);
288 // Mode 0 and mode 1 is for 80x25, 80x50 according to UEFI spec.
292 NewModeBuffer
[ValidCount
].Columns
= 80;
293 NewModeBuffer
[ValidCount
].Rows
= 25;
294 NewModeBuffer
[ValidCount
].GopWidth
= HorizontalResolution
;
295 NewModeBuffer
[ValidCount
].GopHeight
= VerticalResolution
;
296 NewModeBuffer
[ValidCount
].GopModeNumber
= GopModeNumber
;
297 NewModeBuffer
[ValidCount
].DeltaX
= (HorizontalResolution
- (NewModeBuffer
[ValidCount
].Columns
* EFI_GLYPH_WIDTH
)) >> 1;
298 NewModeBuffer
[ValidCount
].DeltaY
= (VerticalResolution
- (NewModeBuffer
[ValidCount
].Rows
* EFI_GLYPH_HEIGHT
)) >> 1;
301 if ((MaxColumns
>= 80) && (MaxRows
>= 50)) {
302 NewModeBuffer
[ValidCount
].Columns
= 80;
303 NewModeBuffer
[ValidCount
].Rows
= 50;
304 NewModeBuffer
[ValidCount
].DeltaX
= (HorizontalResolution
- (80 * EFI_GLYPH_WIDTH
)) >> 1;
305 NewModeBuffer
[ValidCount
].DeltaY
= (VerticalResolution
- (50 * EFI_GLYPH_HEIGHT
)) >> 1;
307 NewModeBuffer
[ValidCount
].GopWidth
= HorizontalResolution
;
308 NewModeBuffer
[ValidCount
].GopHeight
= VerticalResolution
;
309 NewModeBuffer
[ValidCount
].GopModeNumber
= GopModeNumber
;
313 // Start from mode 2 to put the valid mode other than 80x25 and 80x50 in the output mode buffer.
315 for (Index
= 0; Index
< Count
; Index
++) {
316 if ((ModeBuffer
[Index
].Columns
== 0) || (ModeBuffer
[Index
].Rows
== 0) ||
317 (ModeBuffer
[Index
].Columns
> MaxColumns
) || (ModeBuffer
[Index
].Rows
> MaxRows
)) {
319 // Skip the pre-defined mode which is invalid or exceeds the max column and row.
323 for (ValidIndex
= 0; ValidIndex
< ValidCount
; ValidIndex
++) {
324 if ((ModeBuffer
[Index
].Columns
== NewModeBuffer
[ValidIndex
].Columns
) &&
325 (ModeBuffer
[Index
].Rows
== NewModeBuffer
[ValidIndex
].Rows
)) {
327 // Skip the duplicated mode.
332 if (ValidIndex
== ValidCount
) {
333 NewModeBuffer
[ValidCount
].Columns
= ModeBuffer
[Index
].Columns
;
334 NewModeBuffer
[ValidCount
].Rows
= ModeBuffer
[Index
].Rows
;
335 NewModeBuffer
[ValidCount
].GopWidth
= HorizontalResolution
;
336 NewModeBuffer
[ValidCount
].GopHeight
= VerticalResolution
;
337 NewModeBuffer
[ValidCount
].GopModeNumber
= GopModeNumber
;
338 NewModeBuffer
[ValidCount
].DeltaX
= (HorizontalResolution
- (NewModeBuffer
[ValidCount
].Columns
* EFI_GLYPH_WIDTH
)) >> 1;
339 NewModeBuffer
[ValidCount
].DeltaY
= (VerticalResolution
- (NewModeBuffer
[ValidCount
].Rows
* EFI_GLYPH_HEIGHT
)) >> 1;
345 for (Index
= 0; Index
< ValidCount
; Index
++) {
346 DEBUG ((EFI_D_INFO
, "Graphics - Mode %d, Column = %d, Row = %d\n",
347 Index
, NewModeBuffer
[Index
].Columns
, NewModeBuffer
[Index
].Rows
));
352 // Return valid mode count and mode information buffer.
354 *TextModeCount
= ValidCount
;
355 *TextModeData
= NewModeBuffer
;
360 Start this driver on Controller by opening Graphics Output protocol or
361 UGA Draw protocol, and installing Simple Text Out protocol on Controller.
362 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)
364 @param This Protocol instance pointer.
365 @param Controller Handle of device to bind driver to
366 @param RemainingDevicePath Optional parameter use to pick a specific child
369 @retval EFI_SUCCESS This driver is added to Controller.
370 @retval other This driver does not support this device.
375 GraphicsConsoleControllerDriverStart (
376 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
377 IN EFI_HANDLE Controller
,
378 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
382 GRAPHICS_CONSOLE_DEV
*Private
;
383 UINT32 HorizontalResolution
;
384 UINT32 VerticalResolution
;
390 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
*Mode
;
392 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
397 // Initialize the Graphics Console device instance
399 Private
= AllocateCopyPool (
400 sizeof (GRAPHICS_CONSOLE_DEV
),
401 &mGraphicsConsoleDevTemplate
403 if (Private
== NULL
) {
404 return EFI_OUT_OF_RESOURCES
;
407 Private
->SimpleTextOutput
.Mode
= &(Private
->SimpleTextOutputMode
);
409 Status
= gBS
->OpenProtocol (
411 &gEfiGraphicsOutputProtocolGuid
,
412 (VOID
**) &Private
->GraphicsOutput
,
413 This
->DriverBindingHandle
,
415 EFI_OPEN_PROTOCOL_BY_DRIVER
418 if (EFI_ERROR(Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
419 Status
= gBS
->OpenProtocol (
421 &gEfiUgaDrawProtocolGuid
,
422 (VOID
**) &Private
->UgaDraw
,
423 This
->DriverBindingHandle
,
425 EFI_OPEN_PROTOCOL_BY_DRIVER
429 if (EFI_ERROR (Status
)) {
433 HorizontalResolution
= PcdGet32 (PcdVideoHorizontalResolution
);
434 VerticalResolution
= PcdGet32 (PcdVideoVerticalResolution
);
436 if (Private
->GraphicsOutput
!= NULL
) {
438 // The console is build on top of Graphics Output Protocol, find the mode number
439 // for the user-defined mode; if there are multiple video devices,
440 // graphic console driver will set all the video devices to the same mode.
442 if ((HorizontalResolution
== 0x0) || (VerticalResolution
== 0x0)) {
444 // Find the highest resolution which GOP supports.
446 MaxMode
= Private
->GraphicsOutput
->Mode
->MaxMode
;
448 for (ModeIndex
= 0; ModeIndex
< MaxMode
; ModeIndex
++) {
449 Status
= Private
->GraphicsOutput
->QueryMode (
450 Private
->GraphicsOutput
,
455 if (!EFI_ERROR (Status
)) {
456 if ((Info
->HorizontalResolution
> HorizontalResolution
) ||
457 ((Info
->HorizontalResolution
== HorizontalResolution
) && (Info
->VerticalResolution
> VerticalResolution
))) {
458 HorizontalResolution
= Info
->HorizontalResolution
;
459 VerticalResolution
= Info
->VerticalResolution
;
460 ModeNumber
= ModeIndex
;
465 if ((HorizontalResolution
== 0x0) || (VerticalResolution
== 0x0)) {
466 Status
= EFI_UNSUPPORTED
;
471 // Use user-defined resolution
473 Status
= CheckModeSupported (
474 Private
->GraphicsOutput
,
475 HorizontalResolution
,
479 if (EFI_ERROR (Status
)) {
481 // if not supporting current mode, try 800x600 which is required by UEFI/EFI spec
483 HorizontalResolution
= 800;
484 VerticalResolution
= 600;
485 Status
= CheckModeSupported (
486 Private
->GraphicsOutput
,
487 HorizontalResolution
,
491 Mode
= Private
->GraphicsOutput
->Mode
;
492 if (EFI_ERROR (Status
) && Mode
->MaxMode
!= 0) {
494 // Set default mode failed or device don't support default mode, then get the current mode information
496 HorizontalResolution
= Mode
->Info
->HorizontalResolution
;
497 VerticalResolution
= Mode
->Info
->VerticalResolution
;
498 ModeNumber
= Mode
->Mode
;
502 if (ModeNumber
!= Private
->GraphicsOutput
->Mode
->Mode
) {
504 // Current graphics mode is not set or is not set to the mode which we has found,
505 // set the new graphic mode.
507 Status
= Private
->GraphicsOutput
->SetMode (Private
->GraphicsOutput
, ModeNumber
);
508 if (EFI_ERROR (Status
)) {
510 // The mode set operation failed
515 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
517 // At first try to set user-defined resolution
521 Status
= Private
->UgaDraw
->SetMode (
523 HorizontalResolution
,
528 if (EFI_ERROR (Status
)) {
530 // Try to set 800*600 which is required by UEFI/EFI spec
532 Status
= Private
->UgaDraw
->SetMode (
539 if (EFI_ERROR (Status
)) {
540 Status
= Private
->UgaDraw
->GetMode (
542 &HorizontalResolution
,
547 if (EFI_ERROR (Status
)) {
554 DEBUG ((EFI_D_INFO
, "GraphicsConsole video resolution %d x %d\n", HorizontalResolution
, VerticalResolution
));
557 // Initialize the mode which GraphicsConsole supports.
559 Status
= InitializeGraphicsConsoleTextMode (
560 HorizontalResolution
,
567 if (EFI_ERROR (Status
)) {
572 // Update the maximum number of modes
574 Private
->SimpleTextOutputMode
.MaxMode
= (INT32
) MaxMode
;
577 Status
= GraphicsConsoleConOutSetMode (&Private
->SimpleTextOutput
, 0);
578 if (EFI_ERROR (Status
)) {
581 Status
= GraphicsConsoleConOutOutputString (&Private
->SimpleTextOutput
, (CHAR16
*)L
"Graphics Console Started\n\r");
582 if (EFI_ERROR (Status
)) {
588 // Install protocol interfaces for the Graphics Console device.
590 Status
= gBS
->InstallMultipleProtocolInterfaces (
592 &gEfiSimpleTextOutProtocolGuid
,
593 &Private
->SimpleTextOutput
,
598 if (EFI_ERROR (Status
)) {
600 // Close the GOP and UGA Draw Protocol
602 if (Private
->GraphicsOutput
!= NULL
) {
605 &gEfiGraphicsOutputProtocolGuid
,
606 This
->DriverBindingHandle
,
609 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
612 &gEfiUgaDrawProtocolGuid
,
613 This
->DriverBindingHandle
,
618 if (Private
->LineBuffer
!= NULL
) {
619 FreePool (Private
->LineBuffer
);
622 if (Private
->ModeData
!= NULL
) {
623 FreePool (Private
->ModeData
);
636 Stop this driver on Controller by removing Simple Text Out protocol
637 and closing the Graphics Output Protocol or UGA Draw protocol on Controller.
638 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)
641 @param This Protocol instance pointer.
642 @param Controller Handle of device to stop driver on
643 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
644 children is zero stop the entire bus driver.
645 @param ChildHandleBuffer List of Child Handles to Stop.
647 @retval EFI_SUCCESS This driver is removed Controller.
648 @retval EFI_NOT_STARTED Simple Text Out protocol could not be found the
650 @retval other This driver was not removed from this device.
655 GraphicsConsoleControllerDriverStop (
656 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
657 IN EFI_HANDLE Controller
,
658 IN UINTN NumberOfChildren
,
659 IN EFI_HANDLE
*ChildHandleBuffer
663 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
664 GRAPHICS_CONSOLE_DEV
*Private
;
666 Status
= gBS
->OpenProtocol (
668 &gEfiSimpleTextOutProtocolGuid
,
669 (VOID
**) &SimpleTextOutput
,
670 This
->DriverBindingHandle
,
672 EFI_OPEN_PROTOCOL_GET_PROTOCOL
674 if (EFI_ERROR (Status
)) {
675 return EFI_NOT_STARTED
;
678 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
680 Status
= gBS
->UninstallProtocolInterface (
682 &gEfiSimpleTextOutProtocolGuid
,
683 &Private
->SimpleTextOutput
686 if (!EFI_ERROR (Status
)) {
688 // Close the GOP or UGA IO Protocol
690 if (Private
->GraphicsOutput
!= NULL
) {
693 &gEfiGraphicsOutputProtocolGuid
,
694 This
->DriverBindingHandle
,
697 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
700 &gEfiUgaDrawProtocolGuid
,
701 This
->DriverBindingHandle
,
706 if (Private
->LineBuffer
!= NULL
) {
707 FreePool (Private
->LineBuffer
);
710 if (Private
->ModeData
!= NULL
) {
711 FreePool (Private
->ModeData
);
715 // Free our instance data
724 Check if the current specific mode supported the user defined resolution
725 for the Graphics Console device based on Graphics Output Protocol.
727 If yes, set the graphic devcice's current mode to this specific mode.
729 @param GraphicsOutput Graphics Output Protocol instance pointer.
730 @param HorizontalResolution User defined horizontal resolution
731 @param VerticalResolution User defined vertical resolution.
732 @param CurrentModeNumber Current specific mode to be check.
734 @retval EFI_SUCCESS The mode is supported.
735 @retval EFI_UNSUPPORTED The specific mode is out of range of graphics
737 @retval other The specific mode does not support user defined
738 resolution or failed to set the current mode to the
739 specific mode on graphics device.
744 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
745 IN UINT32 HorizontalResolution
,
746 IN UINT32 VerticalResolution
,
747 OUT UINT32
*CurrentModeNumber
753 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
756 Status
= EFI_SUCCESS
;
757 MaxMode
= GraphicsOutput
->Mode
->MaxMode
;
759 for (ModeNumber
= 0; ModeNumber
< MaxMode
; ModeNumber
++) {
760 Status
= GraphicsOutput
->QueryMode (
766 if (!EFI_ERROR (Status
)) {
767 if ((Info
->HorizontalResolution
== HorizontalResolution
) &&
768 (Info
->VerticalResolution
== VerticalResolution
)) {
769 if ((GraphicsOutput
->Mode
->Info
->HorizontalResolution
== HorizontalResolution
) &&
770 (GraphicsOutput
->Mode
->Info
->VerticalResolution
== VerticalResolution
)) {
772 // If video device has been set to this mode, we do not need to SetMode again
777 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeNumber
);
778 if (!EFI_ERROR (Status
)) {
788 if (ModeNumber
== GraphicsOutput
->Mode
->MaxMode
) {
789 Status
= EFI_UNSUPPORTED
;
792 *CurrentModeNumber
= ModeNumber
;
798 Locate HII Database protocol and HII Font protocol.
800 @retval EFI_SUCCESS HII Database protocol and HII Font protocol
801 are located successfully.
802 @return other Failed to locate HII Database protocol or
807 EfiLocateHiiProtocol (
813 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**) &mHiiDatabase
);
814 if (EFI_ERROR (Status
)) {
818 Status
= gBS
->LocateProtocol (&gEfiHiiFontProtocolGuid
, NULL
, (VOID
**) &mHiiFont
);
823 // Body of the STO functions
827 Reset the text output device hardware and optionally run diagnostics.
829 Implements SIMPLE_TEXT_OUTPUT.Reset().
830 If ExtendeVerification is TRUE, then perform dependent Graphics Console
831 device reset, and set display mode to mode 0.
832 If ExtendedVerification is FALSE, only set display mode to mode 0.
834 @param This Protocol instance pointer.
835 @param ExtendedVerification Indicates that the driver may perform a more
836 exhaustive verification operation of the device
839 @retval EFI_SUCCESS The text output device was reset.
840 @retval EFI_DEVICE_ERROR The text output device is not functioning correctly and
846 GraphicsConsoleConOutReset (
847 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
848 IN BOOLEAN ExtendedVerification
852 Status
= This
->SetMode (This
, 0);
853 if (EFI_ERROR (Status
)) {
856 Status
= This
->SetAttribute (This
, EFI_TEXT_ATTR (This
->Mode
->Attribute
& 0x0F, EFI_BACKGROUND_BLACK
));
862 Write a Unicode string to the output device.
864 Implements SIMPLE_TEXT_OUTPUT.OutputString().
865 The Unicode string will be converted to Glyphs and will be
866 sent to the Graphics Console.
868 @param This Protocol instance pointer.
869 @param WString The NULL-terminated Unicode string to be displayed
870 on the output device(s). All output devices must
871 also support the Unicode drawing defined in this file.
873 @retval EFI_SUCCESS The string was output to the device.
874 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output
876 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
878 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
879 characters in the Unicode string could not be
880 rendered and were skipped.
885 GraphicsConsoleConOutOutputString (
886 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
890 GRAPHICS_CONSOLE_DEV
*Private
;
891 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
892 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
901 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
902 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
907 INT32 OriginAttribute
;
910 if (This
->Mode
->Mode
== -1) {
912 // If current mode is not valid, return error.
914 return EFI_UNSUPPORTED
;
917 Status
= EFI_SUCCESS
;
919 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
923 Mode
= This
->Mode
->Mode
;
924 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
925 GraphicsOutput
= Private
->GraphicsOutput
;
926 UgaDraw
= Private
->UgaDraw
;
928 MaxColumn
= Private
->ModeData
[Mode
].Columns
;
929 MaxRow
= Private
->ModeData
[Mode
].Rows
;
930 DeltaX
= (UINTN
) Private
->ModeData
[Mode
].DeltaX
;
931 DeltaY
= (UINTN
) Private
->ModeData
[Mode
].DeltaY
;
932 Width
= MaxColumn
* EFI_GLYPH_WIDTH
;
933 Height
= (MaxRow
- 1) * EFI_GLYPH_HEIGHT
;
934 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
937 // The Attributes won't change when during the time OutputString is called
939 GetTextColors (This
, &Foreground
, &Background
);
948 OriginAttribute
= This
->Mode
->Attribute
;
950 while (*WString
!= L
'\0') {
952 if (*WString
== CHAR_BACKSPACE
) {
954 // If the cursor is at the left edge of the display, then move the cursor
957 if (This
->Mode
->CursorColumn
== 0 && This
->Mode
->CursorRow
> 0) {
958 This
->Mode
->CursorRow
--;
959 This
->Mode
->CursorColumn
= (INT32
) (MaxColumn
- 1);
960 This
->OutputString (This
, SpaceStr
);
962 This
->Mode
->CursorRow
--;
963 This
->Mode
->CursorColumn
= (INT32
) (MaxColumn
- 1);
964 } else if (This
->Mode
->CursorColumn
> 0) {
966 // If the cursor is not at the left edge of the display, then move the cursor
969 This
->Mode
->CursorColumn
--;
970 This
->OutputString (This
, SpaceStr
);
972 This
->Mode
->CursorColumn
--;
977 } else if (*WString
== CHAR_LINEFEED
) {
979 // If the cursor is at the bottom of the display, then scroll the display one
980 // row, and do not update the cursor position. Otherwise, move the cursor
983 if (This
->Mode
->CursorRow
== (INT32
) (MaxRow
- 1)) {
984 if (GraphicsOutput
!= NULL
) {
986 // Scroll Screen Up One Row
988 GraphicsOutput
->Blt (
993 DeltaY
+ EFI_GLYPH_HEIGHT
,
1002 // Print Blank Line at last line
1004 GraphicsOutput
->Blt (
1016 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1018 // Scroll Screen Up One Row
1025 DeltaY
+ EFI_GLYPH_HEIGHT
,
1034 // Print Blank Line at last line
1038 (EFI_UGA_PIXEL
*) (UINTN
) &Background
,
1050 This
->Mode
->CursorRow
++;
1055 } else if (*WString
== CHAR_CARRIAGE_RETURN
) {
1057 // Move the cursor to the beginning of the current row.
1059 This
->Mode
->CursorColumn
= 0;
1062 } else if (*WString
== WIDE_CHAR
) {
1064 This
->Mode
->Attribute
|= EFI_WIDE_ATTRIBUTE
;
1067 } else if (*WString
== NARROW_CHAR
) {
1069 This
->Mode
->Attribute
&= (~ (UINT32
) EFI_WIDE_ATTRIBUTE
);
1074 // Print the character at the current cursor position and move the cursor
1075 // right one column. If this moves the cursor past the right edge of the
1076 // display, then the line should wrap to the beginning of the next line. This
1077 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the
1078 // bottom of the display, and the line wraps, then the display will be scrolled
1080 // If wide char is going to be displayed, need to display one character at a time
1081 // Or, need to know the display length of a certain string.
1083 // Index is used to determine how many character width units (wide = 2, narrow = 1)
1084 // Count is used to determine how many characters are used regardless of their attributes
1086 for (Count
= 0, Index
= 0; (This
->Mode
->CursorColumn
+ Index
) < MaxColumn
; Count
++, Index
++) {
1087 if (WString
[Count
] == CHAR_NULL
||
1088 WString
[Count
] == CHAR_BACKSPACE
||
1089 WString
[Count
] == CHAR_LINEFEED
||
1090 WString
[Count
] == CHAR_CARRIAGE_RETURN
||
1091 WString
[Count
] == WIDE_CHAR
||
1092 WString
[Count
] == NARROW_CHAR
) {
1096 // Is the wide attribute on?
1098 if ((This
->Mode
->Attribute
& EFI_WIDE_ATTRIBUTE
) != 0) {
1100 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop
1104 // This is the end-case where if we are at column 79 and about to print a wide character
1105 // We should prevent this from happening because we will wrap inappropriately. We should
1106 // not print this character until the next line.
1108 if ((This
->Mode
->CursorColumn
+ Index
+ 1) > MaxColumn
) {
1115 Status
= DrawUnicodeWeightAtCursorN (This
, WString
, Count
);
1116 if (EFI_ERROR (Status
)) {
1120 // At the end of line, output carriage return and line feed
1123 This
->Mode
->CursorColumn
+= (INT32
) Index
;
1124 if (This
->Mode
->CursorColumn
> (INT32
) MaxColumn
) {
1125 This
->Mode
->CursorColumn
-= 2;
1126 This
->OutputString (This
, SpaceStr
);
1129 if (This
->Mode
->CursorColumn
>= (INT32
) MaxColumn
) {
1131 This
->OutputString (This
, mCrLfString
);
1137 This
->Mode
->Attribute
= OriginAttribute
;
1142 Status
= EFI_WARN_UNKNOWN_GLYPH
;
1145 gBS
->RestoreTPL (OldTpl
);
1151 Verifies that all characters in a Unicode string can be output to the
1154 Implements SIMPLE_TEXT_OUTPUT.TestString().
1155 If one of the characters in the *Wstring is neither valid valid Unicode
1156 drawing characters, not ASCII code, then this function will return
1159 @param This Protocol instance pointer.
1160 @param WString The NULL-terminated Unicode string to be examined for the output
1163 @retval EFI_SUCCESS The device(s) are capable of rendering the output string.
1164 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be
1165 rendered by one or more of the output devices mapped
1171 GraphicsConsoleConOutTestString (
1172 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1179 EFI_IMAGE_OUTPUT
*Blt
;
1184 while (WString
[Count
] != 0) {
1185 Status
= mHiiFont
->GetGlyph (
1198 if (EFI_ERROR (Status
)) {
1199 return EFI_UNSUPPORTED
;
1208 Returns information for an available text mode that the output device(s)
1211 Implements SIMPLE_TEXT_OUTPUT.QueryMode().
1212 It returnes information for an available text mode that the Graphics Console supports.
1213 In this driver,we only support text mode 80x25, which is defined as mode 0.
1215 @param This Protocol instance pointer.
1216 @param ModeNumber The mode number to return information on.
1217 @param Columns The returned columns of the requested mode.
1218 @param Rows The returned rows of the requested mode.
1220 @retval EFI_SUCCESS The requested mode information is returned.
1221 @retval EFI_UNSUPPORTED The mode number is not valid.
1226 GraphicsConsoleConOutQueryMode (
1227 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1228 IN UINTN ModeNumber
,
1233 GRAPHICS_CONSOLE_DEV
*Private
;
1237 if (ModeNumber
>= (UINTN
) This
->Mode
->MaxMode
) {
1238 return EFI_UNSUPPORTED
;
1241 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1242 Status
= EFI_SUCCESS
;
1244 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1246 *Columns
= Private
->ModeData
[ModeNumber
].Columns
;
1247 *Rows
= Private
->ModeData
[ModeNumber
].Rows
;
1249 if (*Columns
<= 0 || *Rows
<= 0) {
1250 Status
= EFI_UNSUPPORTED
;
1256 gBS
->RestoreTPL (OldTpl
);
1262 Sets the output device(s) to a specified mode.
1264 Implements SIMPLE_TEXT_OUTPUT.SetMode().
1265 Set the Graphics Console to a specified mode. In this driver, we only support mode 0.
1267 @param This Protocol instance pointer.
1268 @param ModeNumber The text mode to set.
1270 @retval EFI_SUCCESS The requested text mode is set.
1271 @retval EFI_DEVICE_ERROR The requested text mode cannot be set because of
1272 Graphics Console device error.
1273 @retval EFI_UNSUPPORTED The text mode number is not valid.
1278 GraphicsConsoleConOutSetMode (
1279 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1284 GRAPHICS_CONSOLE_DEV
*Private
;
1285 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1286 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*NewLineBuffer
;
1287 UINT32 HorizontalResolution
;
1288 UINT32 VerticalResolution
;
1289 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1290 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1295 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1297 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1298 GraphicsOutput
= Private
->GraphicsOutput
;
1299 UgaDraw
= Private
->UgaDraw
;
1302 // Make sure the requested mode number is supported
1304 if (ModeNumber
>= (UINTN
) This
->Mode
->MaxMode
) {
1305 Status
= EFI_UNSUPPORTED
;
1309 ModeData
= &(Private
->ModeData
[ModeNumber
]);
1311 if (ModeData
->Columns
<= 0 && ModeData
->Rows
<= 0) {
1312 Status
= EFI_UNSUPPORTED
;
1317 // If the mode has been set at least one other time, then LineBuffer will not be NULL
1319 if (Private
->LineBuffer
!= NULL
) {
1321 // If the new mode is the same as the old mode, then just return EFI_SUCCESS
1323 if ((INT32
) ModeNumber
== This
->Mode
->Mode
) {
1325 // Clear the current text window on the current graphics console
1327 This
->ClearScreen (This
);
1328 Status
= EFI_SUCCESS
;
1332 // Otherwise, the size of the text console and/or the GOP/UGA mode will be changed,
1333 // so erase the cursor, and free the LineBuffer for the current mode
1337 FreePool (Private
->LineBuffer
);
1341 // Attempt to allocate a line buffer for the requested mode number
1343 NewLineBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * ModeData
->Columns
* EFI_GLYPH_WIDTH
* EFI_GLYPH_HEIGHT
);
1345 if (NewLineBuffer
== NULL
) {
1347 // The new line buffer could not be allocated, so return an error.
1348 // No changes to the state of the current console have been made, so the current console is still valid
1350 Status
= EFI_OUT_OF_RESOURCES
;
1355 // Assign the current line buffer to the newly allocated line buffer
1357 Private
->LineBuffer
= NewLineBuffer
;
1359 if (GraphicsOutput
!= NULL
) {
1360 if (ModeData
->GopModeNumber
!= GraphicsOutput
->Mode
->Mode
) {
1362 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
1364 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeData
->GopModeNumber
);
1365 if (EFI_ERROR (Status
)) {
1367 // The mode set operation failed
1373 // The current graphics mode is correct, so simply clear the entire display
1375 Status
= GraphicsOutput
->Blt (
1377 &mGraphicsEfiColors
[0],
1384 ModeData
->GopHeight
,
1388 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1390 // Get the current UGA Draw mode information
1392 Status
= UgaDraw
->GetMode (
1394 &HorizontalResolution
,
1395 &VerticalResolution
,
1399 if (EFI_ERROR (Status
) || HorizontalResolution
!= ModeData
->GopWidth
|| VerticalResolution
!= ModeData
->GopHeight
) {
1401 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
1403 Status
= UgaDraw
->SetMode (
1406 ModeData
->GopHeight
,
1410 if (EFI_ERROR (Status
)) {
1412 // The mode set operation failed
1418 // The current graphics mode is correct, so simply clear the entire display
1420 Status
= UgaDraw
->Blt (
1422 (EFI_UGA_PIXEL
*) (UINTN
) &mGraphicsEfiColors
[0],
1429 ModeData
->GopHeight
,
1436 // The new mode is valid, so commit the mode change
1438 This
->Mode
->Mode
= (INT32
) ModeNumber
;
1441 // Move the text cursor to the upper left hand corner of the display and flush it
1443 This
->Mode
->CursorColumn
= 0;
1444 This
->Mode
->CursorRow
= 0;
1448 Status
= EFI_SUCCESS
;
1451 gBS
->RestoreTPL (OldTpl
);
1457 Sets the background and foreground colors for the OutputString () and
1458 ClearScreen () functions.
1460 Implements SIMPLE_TEXT_OUTPUT.SetAttribute().
1462 @param This Protocol instance pointer.
1463 @param Attribute The attribute to set. Bits 0..3 are the foreground
1464 color, and bits 4..6 are the background color.
1465 All other bits are undefined and must be zero.
1467 @retval EFI_SUCCESS The requested attribute is set.
1468 @retval EFI_DEVICE_ERROR The requested attribute cannot be set due to Graphics Console port error.
1469 @retval EFI_UNSUPPORTED The attribute requested is not defined.
1474 GraphicsConsoleConOutSetAttribute (
1475 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1481 if ((Attribute
| 0x7F) != 0x7F) {
1482 return EFI_UNSUPPORTED
;
1485 if ((INT32
) Attribute
== This
->Mode
->Attribute
) {
1489 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1493 This
->Mode
->Attribute
= (INT32
) Attribute
;
1497 gBS
->RestoreTPL (OldTpl
);
1504 Clears the output device(s) display to the currently selected background
1507 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().
1509 @param This Protocol instance pointer.
1511 @retval EFI_SUCCESS The operation completed successfully.
1512 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
1513 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
1518 GraphicsConsoleConOutClearScreen (
1519 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
1523 GRAPHICS_CONSOLE_DEV
*Private
;
1524 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1525 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1526 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1527 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
1528 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
1531 if (This
->Mode
->Mode
== -1) {
1533 // If current mode is not valid, return error.
1535 return EFI_UNSUPPORTED
;
1538 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1540 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1541 GraphicsOutput
= Private
->GraphicsOutput
;
1542 UgaDraw
= Private
->UgaDraw
;
1543 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1545 GetTextColors (This
, &Foreground
, &Background
);
1546 if (GraphicsOutput
!= NULL
) {
1547 Status
= GraphicsOutput
->Blt (
1556 ModeData
->GopHeight
,
1559 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1560 Status
= UgaDraw
->Blt (
1562 (EFI_UGA_PIXEL
*) (UINTN
) &Background
,
1569 ModeData
->GopHeight
,
1573 Status
= EFI_UNSUPPORTED
;
1576 This
->Mode
->CursorColumn
= 0;
1577 This
->Mode
->CursorRow
= 0;
1581 gBS
->RestoreTPL (OldTpl
);
1588 Sets the current coordinates of the cursor position.
1590 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().
1592 @param This Protocol instance pointer.
1593 @param Column The position to set the cursor to. Must be greater than or
1594 equal to zero and less than the number of columns and rows
1596 @param Row The position to set the cursor to. Must be greater than or
1597 equal to zero and less than the number of columns and rows
1600 @retval EFI_SUCCESS The operation completed successfully.
1601 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
1602 @retval EFI_UNSUPPORTED The output device is not in a valid text mode, or the
1603 cursor position is invalid for the current mode.
1608 GraphicsConsoleConOutSetCursorPosition (
1609 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1614 GRAPHICS_CONSOLE_DEV
*Private
;
1615 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1619 if (This
->Mode
->Mode
== -1) {
1621 // If current mode is not valid, return error.
1623 return EFI_UNSUPPORTED
;
1626 Status
= EFI_SUCCESS
;
1628 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1630 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1631 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1633 if ((Column
>= ModeData
->Columns
) || (Row
>= ModeData
->Rows
)) {
1634 Status
= EFI_UNSUPPORTED
;
1638 if ((This
->Mode
->CursorColumn
== (INT32
) Column
) && (This
->Mode
->CursorRow
== (INT32
) Row
)) {
1639 Status
= EFI_SUCCESS
;
1645 This
->Mode
->CursorColumn
= (INT32
) Column
;
1646 This
->Mode
->CursorRow
= (INT32
) Row
;
1651 gBS
->RestoreTPL (OldTpl
);
1658 Makes the cursor visible or invisible.
1660 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
1662 @param This Protocol instance pointer.
1663 @param Visible If TRUE, the cursor is set to be visible, If FALSE,
1664 the cursor is set to be invisible.
1666 @retval EFI_SUCCESS The operation completed successfully.
1667 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
1673 GraphicsConsoleConOutEnableCursor (
1674 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1680 if (This
->Mode
->Mode
== -1) {
1682 // If current mode is not valid, return error.
1684 return EFI_UNSUPPORTED
;
1687 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1691 This
->Mode
->CursorVisible
= Visible
;
1695 gBS
->RestoreTPL (OldTpl
);
1700 Gets Graphics Console devcie's foreground color and background color.
1702 @param This Protocol instance pointer.
1703 @param Foreground Returned text foreground color.
1704 @param Background Returned text background color.
1706 @retval EFI_SUCCESS It returned always.
1711 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1712 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Foreground
,
1713 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Background
1718 Attribute
= This
->Mode
->Attribute
& 0x7F;
1720 *Foreground
= mGraphicsEfiColors
[Attribute
& 0x0f];
1721 *Background
= mGraphicsEfiColors
[Attribute
>> 4];
1727 Draw Unicode string on the Graphics Console device's screen.
1729 @param This Protocol instance pointer.
1730 @param UnicodeWeight One Unicode string to be displayed.
1731 @param Count The count of Unicode string.
1733 @retval EFI_OUT_OF_RESOURCES If no memory resource to use.
1734 @retval EFI_UNSUPPORTED If no Graphics Output protocol and UGA Draw
1736 @retval EFI_SUCCESS Drawing Unicode string implemented successfully.
1740 DrawUnicodeWeightAtCursorN (
1741 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1742 IN CHAR16
*UnicodeWeight
,
1747 GRAPHICS_CONSOLE_DEV
*Private
;
1748 EFI_IMAGE_OUTPUT
*Blt
;
1750 EFI_FONT_DISPLAY_INFO
*FontInfo
;
1751 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1752 EFI_HII_ROW_INFO
*RowInfoArray
;
1753 UINTN RowInfoArraySize
;
1755 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1756 Blt
= (EFI_IMAGE_OUTPUT
*) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT
));
1758 return EFI_OUT_OF_RESOURCES
;
1761 Blt
->Width
= (UINT16
) (Private
->ModeData
[This
->Mode
->Mode
].GopWidth
);
1762 Blt
->Height
= (UINT16
) (Private
->ModeData
[This
->Mode
->Mode
].GopHeight
);
1764 String
= AllocateCopyPool ((Count
+ 1) * sizeof (CHAR16
), UnicodeWeight
);
1765 if (String
== NULL
) {
1767 return EFI_OUT_OF_RESOURCES
;
1770 // Set the end character
1772 *(String
+ Count
) = L
'\0';
1774 FontInfo
= (EFI_FONT_DISPLAY_INFO
*) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO
));
1775 if (FontInfo
== NULL
) {
1778 return EFI_OUT_OF_RESOURCES
;
1781 // Get current foreground and background colors.
1783 GetTextColors (This
, &FontInfo
->ForegroundColor
, &FontInfo
->BackgroundColor
);
1785 if (Private
->GraphicsOutput
!= NULL
) {
1787 // If Graphics Output protocol exists, using HII Font protocol to draw.
1789 Blt
->Image
.Screen
= Private
->GraphicsOutput
;
1791 Status
= mHiiFont
->StringToImage (
1793 EFI_HII_IGNORE_IF_NO_GLYPH
| EFI_HII_DIRECT_TO_SCREEN
| EFI_HII_IGNORE_LINE_BREAK
,
1797 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1798 This
->Mode
->CursorRow
* EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1804 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1806 // If Graphics Output protocol cannot be found and PcdUgaConsumeSupport enabled,
1807 // using UGA Draw protocol to draw.
1809 ASSERT (Private
->UgaDraw
!= NULL
);
1811 UgaDraw
= Private
->UgaDraw
;
1813 Blt
->Image
.Bitmap
= AllocateZeroPool (Blt
->Width
* Blt
->Height
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
1814 if (Blt
->Image
.Bitmap
== NULL
) {
1817 return EFI_OUT_OF_RESOURCES
;
1820 RowInfoArray
= NULL
;
1822 // StringToImage only support blt'ing image to device using GOP protocol. If GOP is not supported in this platform,
1823 // we ask StringToImage to print the string to blt buffer, then blt to device using UgaDraw.
1825 Status
= mHiiFont
->StringToImage (
1827 EFI_HII_IGNORE_IF_NO_GLYPH
| EFI_HII_IGNORE_LINE_BREAK
,
1831 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1832 This
->Mode
->CursorRow
* EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1838 if (!EFI_ERROR (Status
)) {
1840 // Line breaks are handled by caller of DrawUnicodeWeightAtCursorN, so the updated parameter RowInfoArraySize by StringToImage will
1841 // always be 1 or 0 (if there is no valid Unicode Char can be printed). ASSERT here to make sure.
1843 ASSERT (RowInfoArraySize
<= 1);
1845 Status
= UgaDraw
->Blt (
1847 (EFI_UGA_PIXEL
*) Blt
->Image
.Bitmap
,
1848 EfiUgaBltBufferToVideo
,
1849 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1850 (This
->Mode
->CursorRow
) * EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1851 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1852 (This
->Mode
->CursorRow
) * EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1853 RowInfoArray
[0].LineWidth
,
1854 RowInfoArray
[0].LineHeight
,
1855 Blt
->Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1859 FreePool (RowInfoArray
);
1860 FreePool (Blt
->Image
.Bitmap
);
1862 Status
= EFI_UNSUPPORTED
;
1868 if (String
!= NULL
) {
1871 if (FontInfo
!= NULL
) {
1872 FreePool (FontInfo
);
1878 Flush the cursor on the screen.
1880 If CursorVisible is FALSE, nothing to do and return directly.
1881 If CursorVisible is TRUE,
1882 i) If the cursor shows on screen, it will be erased.
1883 ii) If the cursor does not show on screen, it will be shown.
1885 @param This Protocol instance pointer.
1887 @retval EFI_SUCCESS The cursor is erased successfully.
1892 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
1895 GRAPHICS_CONSOLE_DEV
*Private
;
1896 EFI_SIMPLE_TEXT_OUTPUT_MODE
*CurrentMode
;
1899 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1900 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1901 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground
;
1902 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background
;
1903 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar
[EFI_GLYPH_HEIGHT
][EFI_GLYPH_WIDTH
];
1907 CurrentMode
= This
->Mode
;
1909 if (!CurrentMode
->CursorVisible
) {
1913 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1914 GraphicsOutput
= Private
->GraphicsOutput
;
1915 UgaDraw
= Private
->UgaDraw
;
1918 // In this driver, only narrow character was supported.
1921 // Blt a character to the screen
1923 GlyphX
= (CurrentMode
->CursorColumn
* EFI_GLYPH_WIDTH
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaX
;
1924 GlyphY
= (CurrentMode
->CursorRow
* EFI_GLYPH_HEIGHT
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaY
;
1925 if (GraphicsOutput
!= NULL
) {
1926 GraphicsOutput
->Blt (
1928 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltChar
,
1929 EfiBltVideoToBltBuffer
,
1936 EFI_GLYPH_WIDTH
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1938 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1941 (EFI_UGA_PIXEL
*) (UINTN
) BltChar
,
1942 EfiUgaVideoToBltBuffer
,
1949 EFI_GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)
1953 GetTextColors (This
, &Foreground
.Pixel
, &Background
.Pixel
);
1956 // Convert Monochrome bitmap of the Glyph to BltBuffer structure
1958 for (PosY
= 0; PosY
< EFI_GLYPH_HEIGHT
; PosY
++) {
1959 for (PosX
= 0; PosX
< EFI_GLYPH_WIDTH
; PosX
++) {
1960 if ((mCursorGlyph
.GlyphCol1
[PosY
] & (BIT0
<< PosX
)) != 0) {
1961 BltChar
[PosY
][EFI_GLYPH_WIDTH
- PosX
- 1].Raw
^= Foreground
.Raw
;
1966 if (GraphicsOutput
!= NULL
) {
1967 GraphicsOutput
->Blt (
1969 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltChar
,
1970 EfiBltBufferToVideo
,
1977 EFI_GLYPH_WIDTH
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1979 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1982 (EFI_UGA_PIXEL
*) (UINTN
) BltChar
,
1983 EfiUgaBltBufferToVideo
,
1990 EFI_GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)
1998 HII Database Protocol notification event handler.
2000 Register font package when HII Database Protocol has been installed.
2002 @param[in] Event Event whose notification function is being invoked.
2003 @param[in] Context Pointer to the notification function's context.
2007 RegisterFontPackage (
2013 EFI_HII_SIMPLE_FONT_PACKAGE_HDR
*SimplifiedFont
;
2014 UINT32 PackageLength
;
2017 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
2020 // Locate HII Database Protocol
2022 Status
= gBS
->LocateProtocol (
2023 &gEfiHiiDatabaseProtocolGuid
,
2025 (VOID
**) &HiiDatabase
2027 if (EFI_ERROR (Status
)) {
2032 // Add 4 bytes to the header for entire length for HiiAddPackages use only.
2034 // +--------------------------------+ <-- Package
2036 // | PackageLength(4 bytes) |
2038 // |--------------------------------| <-- SimplifiedFont
2040 // |EFI_HII_SIMPLE_FONT_PACKAGE_HDR |
2042 // |--------------------------------| <-- Location
2044 // | gUsStdNarrowGlyphData |
2046 // +--------------------------------+
2048 PackageLength
= sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR
) + mNarrowFontSize
+ 4;
2049 Package
= AllocateZeroPool (PackageLength
);
2050 ASSERT (Package
!= NULL
);
2052 WriteUnaligned32((UINT32
*) Package
,PackageLength
);
2053 SimplifiedFont
= (EFI_HII_SIMPLE_FONT_PACKAGE_HDR
*) (Package
+ 4);
2054 SimplifiedFont
->Header
.Length
= (UINT32
) (PackageLength
- 4);
2055 SimplifiedFont
->Header
.Type
= EFI_HII_PACKAGE_SIMPLE_FONTS
;
2056 SimplifiedFont
->NumberOfNarrowGlyphs
= (UINT16
) (mNarrowFontSize
/ sizeof (EFI_NARROW_GLYPH
));
2058 Location
= (UINT8
*) (&SimplifiedFont
->NumberOfWideGlyphs
+ 1);
2059 CopyMem (Location
, gUsStdNarrowGlyphData
, mNarrowFontSize
);
2062 // Add this simplified font package to a package list then install it.
2064 mHiiHandle
= HiiAddPackages (
2065 &mFontPackageListGuid
,
2070 ASSERT (mHiiHandle
!= NULL
);
2075 The user Entry Point for module GraphicsConsole. The user code starts with this function.
2077 @param[in] ImageHandle The firmware allocated handle for the EFI image.
2078 @param[in] SystemTable A pointer to the EFI System Table.
2080 @retval EFI_SUCCESS The entry point is executed successfully.
2081 @return other Some error occurs when executing this entry point.
2086 InitializeGraphicsConsole (
2087 IN EFI_HANDLE ImageHandle
,
2088 IN EFI_SYSTEM_TABLE
*SystemTable
2094 // Register notify function on HII Database Protocol to add font package.
2096 EfiCreateProtocolNotifyEvent (
2097 &gEfiHiiDatabaseProtocolGuid
,
2099 RegisterFontPackage
,
2105 // Install driver model protocol(s).
2107 Status
= EfiLibInstallDriverBindingComponentName2 (
2110 &gGraphicsConsoleDriverBinding
,
2112 &gGraphicsConsoleComponentName
,
2113 &gGraphicsConsoleComponentName2
2115 ASSERT_EFI_ERROR (Status
);