2 This is the main routine for initializing the Graphics Console support routines.
4 Copyright (c) 2006 - 2011, 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 2 entries are specific for PcdConOutRow x PcdConOutColumn and full screen mode.
58 EFI_HII_DATABASE_PROTOCOL
*mHiiDatabase
;
59 EFI_HII_FONT_PROTOCOL
*mHiiFont
;
60 EFI_HII_HANDLE mHiiHandle
;
61 EFI_EVENT mHiiRegistration
;
63 EFI_GUID mFontPackageListGuid
= {0xf5f219d3, 0x7006, 0x4648, {0xac, 0x8d, 0xd6, 0x1d, 0xfb, 0x7b, 0xc6, 0xad}};
65 CHAR16 mCrLfString
[3] = { CHAR_CARRIAGE_RETURN
, CHAR_LINEFEED
, CHAR_NULL
};
67 EFI_GRAPHICS_OUTPUT_BLT_PIXEL mGraphicsEfiColors
[16] = {
71 {0x00, 0x00, 0x00, 0x00}, // BLACK
72 {0x98, 0x00, 0x00, 0x00}, // LIGHTBLUE
73 {0x00, 0x98, 0x00, 0x00}, // LIGHGREEN
74 {0x98, 0x98, 0x00, 0x00}, // LIGHCYAN
75 {0x00, 0x00, 0x98, 0x00}, // LIGHRED
76 {0x98, 0x00, 0x98, 0x00}, // MAGENTA
77 {0x00, 0x98, 0x98, 0x00}, // BROWN
78 {0x98, 0x98, 0x98, 0x00}, // LIGHTGRAY
79 {0x30, 0x30, 0x30, 0x00}, // DARKGRAY - BRIGHT BLACK
80 {0xff, 0x00, 0x00, 0x00}, // BLUE
81 {0x00, 0xff, 0x00, 0x00}, // LIME
82 {0xff, 0xff, 0x00, 0x00}, // CYAN
83 {0x00, 0x00, 0xff, 0x00}, // RED
84 {0xff, 0x00, 0xff, 0x00}, // FUCHSIA
85 {0x00, 0xff, 0xff, 0x00}, // YELLOW
86 {0xff, 0xff, 0xff, 0x00} // WHITE
89 EFI_NARROW_GLYPH mCursorGlyph
= {
92 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF }
95 CHAR16 SpaceStr
[] = { NARROW_CHAR
, ' ', 0 };
97 EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding
= {
98 GraphicsConsoleControllerDriverSupported
,
99 GraphicsConsoleControllerDriverStart
,
100 GraphicsConsoleControllerDriverStop
,
107 Test to see if Graphics Console could be supported on the Controller.
109 Graphics Console could be supported if Graphics Output Protocol or UGA Draw
110 Protocol exists on the Controller. (UGA Draw Protocol could be skipped
111 if PcdUgaConsumeSupport is set to FALSE.)
113 @param This Protocol instance pointer.
114 @param Controller Handle of device to test.
115 @param RemainingDevicePath Optional parameter use to pick a specific child
118 @retval EFI_SUCCESS This driver supports this device.
119 @retval other This driver does not support this device.
124 GraphicsConsoleControllerDriverSupported (
125 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
126 IN EFI_HANDLE Controller
,
127 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
131 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
132 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
133 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
135 GraphicsOutput
= NULL
;
138 // Open the IO Abstraction(s) needed to perform the supported test
140 Status
= gBS
->OpenProtocol (
142 &gEfiGraphicsOutputProtocolGuid
,
143 (VOID
**) &GraphicsOutput
,
144 This
->DriverBindingHandle
,
146 EFI_OPEN_PROTOCOL_BY_DRIVER
149 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
151 // Open Graphics Output Protocol failed, try to open UGA Draw Protocol
153 Status
= gBS
->OpenProtocol (
155 &gEfiUgaDrawProtocolGuid
,
157 This
->DriverBindingHandle
,
159 EFI_OPEN_PROTOCOL_BY_DRIVER
162 if (EFI_ERROR (Status
)) {
167 // We need to ensure that we do not layer on top of a virtual handle.
168 // We need to ensure that the handles produced by the conspliter do not
171 Status
= gBS
->OpenProtocol (
173 &gEfiDevicePathProtocolGuid
,
174 (VOID
**) &DevicePath
,
175 This
->DriverBindingHandle
,
177 EFI_OPEN_PROTOCOL_BY_DRIVER
179 if (!EFI_ERROR (Status
)) {
182 &gEfiDevicePathProtocolGuid
,
183 This
->DriverBindingHandle
,
191 // Does Hii Exist? If not, we aren't ready to run
193 Status
= EfiLocateHiiProtocol ();
196 // Close the I/O Abstraction(s) used to perform the supported test
199 if (GraphicsOutput
!= NULL
) {
202 &gEfiGraphicsOutputProtocolGuid
,
203 This
->DriverBindingHandle
,
206 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
209 &gEfiUgaDrawProtocolGuid
,
210 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 graphis 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
;
256 // Add PcdConOutColumn and PcdConOutRow to the last second entry.
258 Count
= sizeof (mGraphicsConsoleModeData
) / sizeof (GRAPHICS_CONSOLE_MODE_DATA
);
259 mGraphicsConsoleModeData
[Count
- 2].Columns
= (UINTN
) PcdGet32 (PcdConOutColumn
);
260 mGraphicsConsoleModeData
[Count
- 2].Rows
= (UINTN
) PcdGet32 (PcdConOutRow
);
263 // Compute the maximum number of text Rows and Columns that this current graphics mode can support.
264 // To make graphics console work well, MaxColumns and MaxRows should not be zero.
266 MaxColumns
= HorizontalResolution
/ EFI_GLYPH_WIDTH
;
267 MaxRows
= VerticalResolution
/ EFI_GLYPH_HEIGHT
;
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 if ((MaxColumns
>= 80) && (MaxRows
>= 25)) {
295 // 80x25 can be supported.
297 NewModeBuffer
[ValidCount
].Columns
= 80;
298 NewModeBuffer
[ValidCount
].Rows
= 25;
301 // 80x25 cannot be supported, set PCD defined mode.
303 NewModeBuffer
[ValidCount
].Columns
= (UINTN
) PcdGet32 (PcdConOutColumn
);
304 NewModeBuffer
[ValidCount
].Rows
= (UINTN
) PcdGet32 (PcdConOutRow
);
306 NewModeBuffer
[ValidCount
].GopWidth
= HorizontalResolution
;
307 NewModeBuffer
[ValidCount
].GopHeight
= VerticalResolution
;
308 NewModeBuffer
[ValidCount
].GopModeNumber
= GopModeNumber
;
309 NewModeBuffer
[ValidCount
].DeltaX
= (HorizontalResolution
- (NewModeBuffer
[ValidCount
].Columns
* EFI_GLYPH_WIDTH
)) >> 1;
310 NewModeBuffer
[ValidCount
].DeltaY
= (VerticalResolution
- (NewModeBuffer
[ValidCount
].Rows
* EFI_GLYPH_HEIGHT
)) >> 1;
313 if ((MaxColumns
>= 80) && (MaxRows
>= 50)) {
314 NewModeBuffer
[ValidCount
].Columns
= 80;
315 NewModeBuffer
[ValidCount
].Rows
= 50;
316 NewModeBuffer
[ValidCount
].DeltaX
= (HorizontalResolution
- (80 * EFI_GLYPH_WIDTH
)) >> 1;
317 NewModeBuffer
[ValidCount
].DeltaY
= (VerticalResolution
- (50 * EFI_GLYPH_HEIGHT
)) >> 1;
319 NewModeBuffer
[ValidCount
].GopWidth
= HorizontalResolution
;
320 NewModeBuffer
[ValidCount
].GopHeight
= VerticalResolution
;
321 NewModeBuffer
[ValidCount
].GopModeNumber
= GopModeNumber
;
325 // Start from mode 2 to put the valid mode other than 80x25 and 80x50 in the output mode buffer.
327 for (Index
= 0; Index
< Count
; Index
++) {
328 if ((ModeBuffer
[Index
].Columns
== 0) || (ModeBuffer
[Index
].Rows
== 0) ||
329 (ModeBuffer
[Index
].Columns
> MaxColumns
) || (ModeBuffer
[Index
].Rows
> MaxRows
)) {
331 // Skip the pre-defined mode which is invalid or exceeds the max column and row.
335 for (ValidIndex
= 0; ValidIndex
< ValidCount
; ValidIndex
++) {
336 if ((ModeBuffer
[Index
].Columns
== NewModeBuffer
[ValidIndex
].Columns
) &&
337 (ModeBuffer
[Index
].Rows
== NewModeBuffer
[ValidIndex
].Rows
)) {
339 // Skip the duplicated mode.
344 if (ValidIndex
== ValidCount
) {
345 NewModeBuffer
[ValidCount
].Columns
= ModeBuffer
[Index
].Columns
;
346 NewModeBuffer
[ValidCount
].Rows
= ModeBuffer
[Index
].Rows
;
347 NewModeBuffer
[ValidCount
].GopWidth
= HorizontalResolution
;
348 NewModeBuffer
[ValidCount
].GopHeight
= VerticalResolution
;
349 NewModeBuffer
[ValidCount
].GopModeNumber
= GopModeNumber
;
350 NewModeBuffer
[ValidCount
].DeltaX
= (HorizontalResolution
- (NewModeBuffer
[ValidCount
].Columns
* EFI_GLYPH_WIDTH
)) >> 1;
351 NewModeBuffer
[ValidCount
].DeltaY
= (VerticalResolution
- (NewModeBuffer
[ValidCount
].Rows
* EFI_GLYPH_HEIGHT
)) >> 1;
357 for (Index
= 0; Index
< ValidCount
; Index
++) {
358 DEBUG ((EFI_D_INFO
, "Graphics - Mode %d, Column = %d, Row = %d\n",
359 Index
, NewModeBuffer
[Index
].Columns
, 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
;
409 // Initialize the Graphics Console device instance
411 Private
= AllocateCopyPool (
412 sizeof (GRAPHICS_CONSOLE_DEV
),
413 &mGraphicsConsoleDevTemplate
415 if (Private
== NULL
) {
416 return EFI_OUT_OF_RESOURCES
;
419 Private
->SimpleTextOutput
.Mode
= &(Private
->SimpleTextOutputMode
);
421 Status
= gBS
->OpenProtocol (
423 &gEfiGraphicsOutputProtocolGuid
,
424 (VOID
**) &Private
->GraphicsOutput
,
425 This
->DriverBindingHandle
,
427 EFI_OPEN_PROTOCOL_BY_DRIVER
430 if (EFI_ERROR(Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
431 Status
= gBS
->OpenProtocol (
433 &gEfiUgaDrawProtocolGuid
,
434 (VOID
**) &Private
->UgaDraw
,
435 This
->DriverBindingHandle
,
437 EFI_OPEN_PROTOCOL_BY_DRIVER
441 if (EFI_ERROR (Status
)) {
445 HorizontalResolution
= PcdGet32 (PcdVideoHorizontalResolution
);
446 VerticalResolution
= PcdGet32 (PcdVideoVerticalResolution
);
448 if (Private
->GraphicsOutput
!= NULL
) {
450 // The console is build on top of Graphics Output Protocol, find the mode number
451 // for the user-defined mode; if there are multiple video devices,
452 // graphic console driver will set all the video devices to the same mode.
454 if ((HorizontalResolution
== 0x0) || (VerticalResolution
== 0x0)) {
456 // Find the highest resolution which GOP supports.
458 MaxMode
= Private
->GraphicsOutput
->Mode
->MaxMode
;
460 for (ModeIndex
= 0; ModeIndex
< MaxMode
; ModeIndex
++) {
461 Status
= Private
->GraphicsOutput
->QueryMode (
462 Private
->GraphicsOutput
,
467 if (!EFI_ERROR (Status
)) {
468 if ((Info
->HorizontalResolution
>= HorizontalResolution
) &&
469 (Info
->VerticalResolution
>= VerticalResolution
)) {
470 HorizontalResolution
= Info
->HorizontalResolution
;
471 VerticalResolution
= Info
->VerticalResolution
;
472 ModeNumber
= ModeIndex
;
477 if ((HorizontalResolution
== 0x0) || (VerticalResolution
== 0x0)) {
478 Status
= EFI_UNSUPPORTED
;
483 // Use user-defined resolution
485 Status
= CheckModeSupported (
486 Private
->GraphicsOutput
,
487 HorizontalResolution
,
491 if (EFI_ERROR (Status
)) {
493 // if not supporting current mode, try 800x600 which is required by UEFI/EFI spec
495 Status
= CheckModeSupported (
496 Private
->GraphicsOutput
,
501 Mode
= Private
->GraphicsOutput
->Mode
;
502 if (EFI_ERROR (Status
) && Mode
->MaxMode
!= 0) {
504 // Set default mode failed or device don't support default mode, then get the current mode information
506 HorizontalResolution
= Mode
->Info
->HorizontalResolution
;
507 VerticalResolution
= Mode
->Info
->VerticalResolution
;
508 ModeNumber
= Mode
->Mode
;
512 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
514 // At first try to set user-defined resolution
518 Status
= Private
->UgaDraw
->SetMode (
520 HorizontalResolution
,
525 if (EFI_ERROR (Status
)) {
527 // Try to set 800*600 which is required by UEFI/EFI spec
529 Status
= Private
->UgaDraw
->SetMode (
536 if (EFI_ERROR (Status
)) {
537 Status
= Private
->UgaDraw
->GetMode (
539 &HorizontalResolution
,
544 if (EFI_ERROR (Status
)) {
549 Status
= EFI_UNSUPPORTED
;
555 // Initialize the mode which GraphicsConsole supports.
557 Status
= InitializeGraphicsConsoleTextMode (
558 HorizontalResolution
,
565 if (EFI_ERROR (Status
)) {
570 // Update the maximum number of modes
572 Private
->SimpleTextOutputMode
.MaxMode
= (INT32
) MaxMode
;
575 // Determine the number of text modes that this protocol can support
577 Status
= GraphicsConsoleConOutSetMode (&Private
->SimpleTextOutput
, 0);
578 if (EFI_ERROR (Status
)) {
583 GraphicsConsoleConOutOutputString (&Private
->SimpleTextOutput
, (CHAR16
*)L
"Graphics Console Started\n\r");
587 // Install protocol interfaces for the Graphics Console device.
589 Status
= gBS
->InstallMultipleProtocolInterfaces (
591 &gEfiSimpleTextOutProtocolGuid
,
592 &Private
->SimpleTextOutput
,
597 if (EFI_ERROR (Status
)) {
599 // Close the GOP and UGA Draw Protocol
601 if (Private
->GraphicsOutput
!= NULL
) {
604 &gEfiGraphicsOutputProtocolGuid
,
605 This
->DriverBindingHandle
,
608 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
611 &gEfiUgaDrawProtocolGuid
,
612 This
->DriverBindingHandle
,
617 if (Private
->LineBuffer
!= NULL
) {
618 FreePool (Private
->LineBuffer
);
621 if (Private
->ModeData
!= NULL
) {
622 FreePool (Private
->ModeData
);
635 Stop this driver on Controller by removing Simple Text Out protocol
636 and closing the Graphics Output Protocol or UGA Draw protocol on Controller.
637 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)
640 @param This Protocol instance pointer.
641 @param Controller Handle of device to stop driver on
642 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
643 children is zero stop the entire bus driver.
644 @param ChildHandleBuffer List of Child Handles to Stop.
646 @retval EFI_SUCCESS This driver is removed Controller.
647 @retval EFI_NOT_STARTED Simple Text Out protocol could not be found the
649 @retval other This driver was not removed from this device.
654 GraphicsConsoleControllerDriverStop (
655 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
656 IN EFI_HANDLE Controller
,
657 IN UINTN NumberOfChildren
,
658 IN EFI_HANDLE
*ChildHandleBuffer
662 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
663 GRAPHICS_CONSOLE_DEV
*Private
;
665 Status
= gBS
->OpenProtocol (
667 &gEfiSimpleTextOutProtocolGuid
,
668 (VOID
**) &SimpleTextOutput
,
669 This
->DriverBindingHandle
,
671 EFI_OPEN_PROTOCOL_GET_PROTOCOL
673 if (EFI_ERROR (Status
)) {
674 return EFI_NOT_STARTED
;
677 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
679 Status
= gBS
->UninstallProtocolInterface (
681 &gEfiSimpleTextOutProtocolGuid
,
682 &Private
->SimpleTextOutput
685 if (!EFI_ERROR (Status
)) {
687 // Close the GOP or UGA IO Protocol
689 if (Private
->GraphicsOutput
!= NULL
) {
692 &gEfiGraphicsOutputProtocolGuid
,
693 This
->DriverBindingHandle
,
696 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
699 &gEfiUgaDrawProtocolGuid
,
700 This
->DriverBindingHandle
,
705 if (Private
->LineBuffer
!= NULL
) {
706 FreePool (Private
->LineBuffer
);
709 if (Private
->ModeData
!= NULL
) {
710 FreePool (Private
->ModeData
);
714 // Free our instance data
723 Check if the current specific mode supported the user defined resolution
724 for the Graphics Console device based on Graphics Output Protocol.
726 If yes, set the graphic devcice's current mode to this specific mode.
728 @param GraphicsOutput Graphics Output Protocol instance pointer.
729 @param HorizontalResolution User defined horizontal resolution
730 @param VerticalResolution User defined vertical resolution.
731 @param CurrentModeNumber Current specific mode to be check.
733 @retval EFI_SUCCESS The mode is supported.
734 @retval EFI_UNSUPPORTED The specific mode is out of range of graphics
736 @retval other The specific mode does not support user defined
737 resolution or failed to set the current mode to the
738 specific mode on graphics device.
743 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
744 IN UINT32 HorizontalResolution
,
745 IN UINT32 VerticalResolution
,
746 OUT UINT32
*CurrentModeNumber
752 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
755 Status
= EFI_SUCCESS
;
756 MaxMode
= GraphicsOutput
->Mode
->MaxMode
;
758 for (ModeNumber
= 0; ModeNumber
< MaxMode
; ModeNumber
++) {
759 Status
= GraphicsOutput
->QueryMode (
765 if (!EFI_ERROR (Status
)) {
766 if ((Info
->HorizontalResolution
== HorizontalResolution
) &&
767 (Info
->VerticalResolution
== VerticalResolution
)) {
768 if ((GraphicsOutput
->Mode
->Info
->HorizontalResolution
== HorizontalResolution
) &&
769 (GraphicsOutput
->Mode
->Info
->VerticalResolution
== VerticalResolution
)) {
771 // If video device has been set to this mode, we do not need to SetMode again
775 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeNumber
);
776 if (!EFI_ERROR (Status
)) {
786 if (ModeNumber
== GraphicsOutput
->Mode
->MaxMode
) {
787 Status
= EFI_UNSUPPORTED
;
790 *CurrentModeNumber
= ModeNumber
;
796 Locate HII Database protocol and HII Font protocol.
798 @retval EFI_SUCCESS HII Database protocol and HII Font protocol
799 are located successfully.
800 @return other Failed to locate HII Database protocol or
805 EfiLocateHiiProtocol (
814 // There should only be one - so buffer size is this
816 Size
= sizeof (EFI_HANDLE
);
818 Status
= gBS
->LocateHandle (
820 &gEfiHiiDatabaseProtocolGuid
,
826 if (EFI_ERROR (Status
)) {
830 Status
= gBS
->HandleProtocol (
832 &gEfiHiiDatabaseProtocolGuid
,
833 (VOID
**) &mHiiDatabase
836 if (EFI_ERROR (Status
)) {
840 Status
= gBS
->HandleProtocol (
842 &gEfiHiiFontProtocolGuid
,
849 // Body of the STO functions
853 Reset the text output device hardware and optionally run diagnostics.
855 Implements SIMPLE_TEXT_OUTPUT.Reset().
856 If ExtendeVerification is TRUE, then perform dependent Graphics Console
857 device reset, and set display mode to mode 0.
858 If ExtendedVerification is FALSE, only set display mode to mode 0.
860 @param This Protocol instance pointer.
861 @param ExtendedVerification Indicates that the driver may perform a more
862 exhaustive verification operation of the device
865 @retval EFI_SUCCESS The text output device was reset.
866 @retval EFI_DEVICE_ERROR The text output device is not functioning correctly and
872 GraphicsConsoleConOutReset (
873 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
874 IN BOOLEAN ExtendedVerification
877 This
->SetAttribute (This
, EFI_TEXT_ATTR (This
->Mode
->Attribute
& 0x0F, EFI_BACKGROUND_BLACK
));
878 return This
->SetMode (This
, 0);
883 Write a Unicode string to the output device.
885 Implements SIMPLE_TEXT_OUTPUT.OutputString().
886 The Unicode string will be converted to Glyphs and will be
887 sent to the Graphics Console.
889 @param This Protocol instance pointer.
890 @param WString The NULL-terminated Unicode string to be displayed
891 on the output device(s). All output devices must
892 also support the Unicode drawing defined in this file.
894 @retval EFI_SUCCESS The string was output to the device.
895 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output
897 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
899 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
900 characters in the Unicode string could not be
901 rendered and were skipped.
906 GraphicsConsoleConOutOutputString (
907 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
911 GRAPHICS_CONSOLE_DEV
*Private
;
912 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
913 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
922 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
923 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
928 INT32 OriginAttribute
;
931 Status
= EFI_SUCCESS
;
933 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
937 Mode
= This
->Mode
->Mode
;
938 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
939 GraphicsOutput
= Private
->GraphicsOutput
;
940 UgaDraw
= Private
->UgaDraw
;
942 MaxColumn
= Private
->ModeData
[Mode
].Columns
;
943 MaxRow
= Private
->ModeData
[Mode
].Rows
;
944 DeltaX
= (UINTN
) Private
->ModeData
[Mode
].DeltaX
;
945 DeltaY
= (UINTN
) Private
->ModeData
[Mode
].DeltaY
;
946 Width
= MaxColumn
* EFI_GLYPH_WIDTH
;
947 Height
= (MaxRow
- 1) * EFI_GLYPH_HEIGHT
;
948 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
951 // The Attributes won't change when during the time OutputString is called
953 GetTextColors (This
, &Foreground
, &Background
);
962 OriginAttribute
= This
->Mode
->Attribute
;
964 while (*WString
!= L
'\0') {
966 if (*WString
== CHAR_BACKSPACE
) {
968 // If the cursor is at the left edge of the display, then move the cursor
971 if (This
->Mode
->CursorColumn
== 0 && This
->Mode
->CursorRow
> 0) {
972 This
->Mode
->CursorRow
--;
973 This
->Mode
->CursorColumn
= (INT32
) (MaxColumn
- 1);
974 This
->OutputString (This
, SpaceStr
);
976 This
->Mode
->CursorRow
--;
977 This
->Mode
->CursorColumn
= (INT32
) (MaxColumn
- 1);
978 } else if (This
->Mode
->CursorColumn
> 0) {
980 // If the cursor is not at the left edge of the display, then move the cursor
983 This
->Mode
->CursorColumn
--;
984 This
->OutputString (This
, SpaceStr
);
986 This
->Mode
->CursorColumn
--;
991 } else if (*WString
== CHAR_LINEFEED
) {
993 // If the cursor is at the bottom of the display, then scroll the display one
994 // row, and do not update the cursor position. Otherwise, move the cursor
997 if (This
->Mode
->CursorRow
== (INT32
) (MaxRow
- 1)) {
998 if (GraphicsOutput
!= NULL
) {
1000 // Scroll Screen Up One Row
1002 GraphicsOutput
->Blt (
1007 DeltaY
+ EFI_GLYPH_HEIGHT
,
1016 // Print Blank Line at last line
1018 GraphicsOutput
->Blt (
1030 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1032 // Scroll Screen Up One Row
1039 DeltaY
+ EFI_GLYPH_HEIGHT
,
1048 // Print Blank Line at last line
1052 (EFI_UGA_PIXEL
*) (UINTN
) &Background
,
1064 This
->Mode
->CursorRow
++;
1069 } else if (*WString
== CHAR_CARRIAGE_RETURN
) {
1071 // Move the cursor to the beginning of the current row.
1073 This
->Mode
->CursorColumn
= 0;
1076 } else if (*WString
== WIDE_CHAR
) {
1078 This
->Mode
->Attribute
|= EFI_WIDE_ATTRIBUTE
;
1081 } else if (*WString
== NARROW_CHAR
) {
1083 This
->Mode
->Attribute
&= (~ (UINT32
) EFI_WIDE_ATTRIBUTE
);
1088 // Print the character at the current cursor position and move the cursor
1089 // right one column. If this moves the cursor past the right edge of the
1090 // display, then the line should wrap to the beginning of the next line. This
1091 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the
1092 // bottom of the display, and the line wraps, then the display will be scrolled
1094 // If wide char is going to be displayed, need to display one character at a time
1095 // Or, need to know the display length of a certain string.
1097 // Index is used to determine how many character width units (wide = 2, narrow = 1)
1098 // Count is used to determine how many characters are used regardless of their attributes
1100 for (Count
= 0, Index
= 0; (This
->Mode
->CursorColumn
+ Index
) < MaxColumn
; Count
++, Index
++) {
1101 if (WString
[Count
] == CHAR_NULL
||
1102 WString
[Count
] == CHAR_BACKSPACE
||
1103 WString
[Count
] == CHAR_LINEFEED
||
1104 WString
[Count
] == CHAR_CARRIAGE_RETURN
||
1105 WString
[Count
] == WIDE_CHAR
||
1106 WString
[Count
] == NARROW_CHAR
) {
1110 // Is the wide attribute on?
1112 if ((This
->Mode
->Attribute
& EFI_WIDE_ATTRIBUTE
) != 0) {
1114 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop
1118 // This is the end-case where if we are at column 79 and about to print a wide character
1119 // We should prevent this from happening because we will wrap inappropriately. We should
1120 // not print this character until the next line.
1122 if ((This
->Mode
->CursorColumn
+ Index
+ 1) > MaxColumn
) {
1129 Status
= DrawUnicodeWeightAtCursorN (This
, WString
, Count
);
1130 if (EFI_ERROR (Status
)) {
1134 // At the end of line, output carriage return and line feed
1137 This
->Mode
->CursorColumn
+= (INT32
) Index
;
1138 if (This
->Mode
->CursorColumn
> (INT32
) MaxColumn
) {
1139 This
->Mode
->CursorColumn
-= 2;
1140 This
->OutputString (This
, SpaceStr
);
1143 if (This
->Mode
->CursorColumn
>= (INT32
) MaxColumn
) {
1145 This
->OutputString (This
, mCrLfString
);
1151 This
->Mode
->Attribute
= OriginAttribute
;
1156 Status
= EFI_WARN_UNKNOWN_GLYPH
;
1159 gBS
->RestoreTPL (OldTpl
);
1165 Verifies that all characters in a Unicode string can be output to the
1168 Implements SIMPLE_TEXT_OUTPUT.TestString().
1169 If one of the characters in the *Wstring is neither valid valid Unicode
1170 drawing characters, not ASCII code, then this function will return
1173 @param This Protocol instance pointer.
1174 @param WString The NULL-terminated Unicode string to be examined for the output
1177 @retval EFI_SUCCESS The device(s) are capable of rendering the output string.
1178 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be
1179 rendered by one or more of the output devices mapped
1185 GraphicsConsoleConOutTestString (
1186 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1193 EFI_IMAGE_OUTPUT
*Blt
;
1198 while (WString
[Count
] != 0) {
1199 Status
= mHiiFont
->GetGlyph (
1212 if (EFI_ERROR (Status
)) {
1213 return EFI_UNSUPPORTED
;
1222 Returns information for an available text mode that the output device(s)
1225 Implements SIMPLE_TEXT_OUTPUT.QueryMode().
1226 It returnes information for an available text mode that the Graphics Console supports.
1227 In this driver,we only support text mode 80x25, which is defined as mode 0.
1229 @param This Protocol instance pointer.
1230 @param ModeNumber The mode number to return information on.
1231 @param Columns The returned columns of the requested mode.
1232 @param Rows The returned rows of the requested mode.
1234 @retval EFI_SUCCESS The requested mode information is returned.
1235 @retval EFI_UNSUPPORTED The mode number is not valid.
1240 GraphicsConsoleConOutQueryMode (
1241 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1242 IN UINTN ModeNumber
,
1247 GRAPHICS_CONSOLE_DEV
*Private
;
1251 if (ModeNumber
>= (UINTN
) This
->Mode
->MaxMode
) {
1252 return EFI_UNSUPPORTED
;
1255 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1256 Status
= EFI_SUCCESS
;
1258 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1260 *Columns
= Private
->ModeData
[ModeNumber
].Columns
;
1261 *Rows
= Private
->ModeData
[ModeNumber
].Rows
;
1263 if (*Columns
<= 0 || *Rows
<= 0) {
1264 Status
= EFI_UNSUPPORTED
;
1270 gBS
->RestoreTPL (OldTpl
);
1276 Sets the output device(s) to a specified mode.
1278 Implements SIMPLE_TEXT_OUTPUT.SetMode().
1279 Set the Graphics Console to a specified mode. In this driver, we only support mode 0.
1281 @param This Protocol instance pointer.
1282 @param ModeNumber The text mode to set.
1284 @retval EFI_SUCCESS The requested text mode is set.
1285 @retval EFI_DEVICE_ERROR The requested text mode cannot be set because of
1286 Graphics Console device error.
1287 @retval EFI_UNSUPPORTED The text mode number is not valid.
1292 GraphicsConsoleConOutSetMode (
1293 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1298 GRAPHICS_CONSOLE_DEV
*Private
;
1299 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1300 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*NewLineBuffer
;
1301 UINT32 HorizontalResolution
;
1302 UINT32 VerticalResolution
;
1303 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1304 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1309 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1311 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1312 GraphicsOutput
= Private
->GraphicsOutput
;
1313 UgaDraw
= Private
->UgaDraw
;
1314 ModeData
= &(Private
->ModeData
[ModeNumber
]);
1317 // Make sure the requested mode number is supported
1319 if (ModeNumber
>= (UINTN
) This
->Mode
->MaxMode
) {
1320 Status
= EFI_UNSUPPORTED
;
1324 if (ModeData
->Columns
<= 0 && ModeData
->Rows
<= 0) {
1325 Status
= EFI_UNSUPPORTED
;
1329 // Attempt to allocate a line buffer for the requested mode number
1331 NewLineBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * ModeData
->Columns
* EFI_GLYPH_WIDTH
* EFI_GLYPH_HEIGHT
);
1333 if (NewLineBuffer
== NULL
) {
1335 // The new line buffer could not be allocated, so return an error.
1336 // No changes to the state of the current console have been made, so the current console is still valid
1338 Status
= EFI_OUT_OF_RESOURCES
;
1342 // If the mode has been set at least one other time, then LineBuffer will not be NULL
1344 if (Private
->LineBuffer
!= NULL
) {
1346 // Clear the current text window on the current graphics console
1348 This
->ClearScreen (This
);
1351 // If the new mode is the same as the old mode, then just return EFI_SUCCESS
1353 if ((INT32
) ModeNumber
== This
->Mode
->Mode
) {
1354 FreePool (NewLineBuffer
);
1355 Status
= EFI_SUCCESS
;
1359 // Otherwise, the size of the text console and/or the GOP/UGA mode will be changed,
1360 // so erase the cursor, and free the LineBuffer for the current mode
1364 FreePool (Private
->LineBuffer
);
1367 // Assign the current line buffer to the newly allocated line buffer
1369 Private
->LineBuffer
= NewLineBuffer
;
1371 if (GraphicsOutput
!= NULL
) {
1372 if (ModeData
->GopModeNumber
!= GraphicsOutput
->Mode
->Mode
) {
1374 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
1376 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeData
->GopModeNumber
);
1377 if (EFI_ERROR (Status
)) {
1379 // The mode set operation failed
1385 // The current graphics mode is correct, so simply clear the entire display
1387 Status
= GraphicsOutput
->Blt (
1389 &mGraphicsEfiColors
[0],
1396 ModeData
->GopHeight
,
1400 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1402 // Get the current UGA Draw mode information
1404 Status
= UgaDraw
->GetMode (
1406 &HorizontalResolution
,
1407 &VerticalResolution
,
1411 if (EFI_ERROR (Status
) || HorizontalResolution
!= ModeData
->GopWidth
|| VerticalResolution
!= ModeData
->GopHeight
) {
1413 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
1415 Status
= UgaDraw
->SetMode (
1418 ModeData
->GopHeight
,
1422 if (EFI_ERROR (Status
)) {
1424 // The mode set operation failed
1430 // The current graphics mode is correct, so simply clear the entire display
1432 Status
= UgaDraw
->Blt (
1434 (EFI_UGA_PIXEL
*) (UINTN
) &mGraphicsEfiColors
[0],
1441 ModeData
->GopHeight
,
1448 // The new mode is valid, so commit the mode change
1450 This
->Mode
->Mode
= (INT32
) ModeNumber
;
1453 // Move the text cursor to the upper left hand corner of the display and flush it
1455 This
->Mode
->CursorColumn
= 0;
1456 This
->Mode
->CursorRow
= 0;
1460 Status
= EFI_SUCCESS
;
1463 gBS
->RestoreTPL (OldTpl
);
1469 Sets the background and foreground colors for the OutputString () and
1470 ClearScreen () functions.
1472 Implements SIMPLE_TEXT_OUTPUT.SetAttribute().
1474 @param This Protocol instance pointer.
1475 @param Attribute The attribute to set. Bits 0..3 are the foreground
1476 color, and bits 4..6 are the background color.
1477 All other bits are undefined and must be zero.
1479 @retval EFI_SUCCESS The requested attribute is set.
1480 @retval EFI_DEVICE_ERROR The requested attribute cannot be set due to Graphics Console port error.
1481 @retval EFI_UNSUPPORTED The attribute requested is not defined.
1486 GraphicsConsoleConOutSetAttribute (
1487 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1493 if ((Attribute
| 0xFF) != 0xFF) {
1494 return EFI_UNSUPPORTED
;
1497 if ((INT32
) Attribute
== This
->Mode
->Attribute
) {
1501 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1505 This
->Mode
->Attribute
= (INT32
) Attribute
;
1509 gBS
->RestoreTPL (OldTpl
);
1516 Clears the output device(s) display to the currently selected background
1519 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().
1521 @param This Protocol instance pointer.
1523 @retval EFI_SUCCESS The operation completed successfully.
1524 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
1525 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
1530 GraphicsConsoleConOutClearScreen (
1531 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
1535 GRAPHICS_CONSOLE_DEV
*Private
;
1536 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1537 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1538 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1539 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
1540 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
1543 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1545 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1546 GraphicsOutput
= Private
->GraphicsOutput
;
1547 UgaDraw
= Private
->UgaDraw
;
1548 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1550 GetTextColors (This
, &Foreground
, &Background
);
1551 if (GraphicsOutput
!= NULL
) {
1552 Status
= GraphicsOutput
->Blt (
1561 ModeData
->GopHeight
,
1564 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1565 Status
= UgaDraw
->Blt (
1567 (EFI_UGA_PIXEL
*) (UINTN
) &Background
,
1574 ModeData
->GopHeight
,
1578 Status
= EFI_UNSUPPORTED
;
1581 This
->Mode
->CursorColumn
= 0;
1582 This
->Mode
->CursorRow
= 0;
1586 gBS
->RestoreTPL (OldTpl
);
1593 Sets the current coordinates of the cursor position.
1595 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().
1597 @param This Protocol instance pointer.
1598 @param Column The position to set the cursor to. Must be greater than or
1599 equal to zero and less than the number of columns and rows
1601 @param Row The position to set the cursor to. Must be greater than or
1602 equal to zero and less than the number of columns and rows
1605 @retval EFI_SUCCESS The operation completed successfully.
1606 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
1607 @retval EFI_UNSUPPORTED The output device is not in a valid text mode, or the
1608 cursor position is invalid for the current mode.
1613 GraphicsConsoleConOutSetCursorPosition (
1614 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1619 GRAPHICS_CONSOLE_DEV
*Private
;
1620 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1624 Status
= EFI_SUCCESS
;
1626 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1628 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1629 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1631 if ((Column
>= ModeData
->Columns
) || (Row
>= ModeData
->Rows
)) {
1632 Status
= EFI_UNSUPPORTED
;
1636 if ((This
->Mode
->CursorColumn
== (INT32
) Column
) && (This
->Mode
->CursorRow
== (INT32
) Row
)) {
1637 Status
= EFI_SUCCESS
;
1643 This
->Mode
->CursorColumn
= (INT32
) Column
;
1644 This
->Mode
->CursorRow
= (INT32
) Row
;
1649 gBS
->RestoreTPL (OldTpl
);
1656 Makes the cursor visible or invisible.
1658 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
1660 @param This Protocol instance pointer.
1661 @param Visible If TRUE, the cursor is set to be visible, If FALSE,
1662 the cursor is set to be invisible.
1664 @retval EFI_SUCCESS The operation completed successfully.
1669 GraphicsConsoleConOutEnableCursor (
1670 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1676 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1680 This
->Mode
->CursorVisible
= Visible
;
1684 gBS
->RestoreTPL (OldTpl
);
1689 Gets Graphics Console devcie's foreground color and background color.
1691 @param This Protocol instance pointer.
1692 @param Foreground Returned text foreground color.
1693 @param Background Returned text background color.
1695 @retval EFI_SUCCESS It returned always.
1700 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1701 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Foreground
,
1702 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Background
1707 Attribute
= This
->Mode
->Attribute
& 0x7F;
1709 *Foreground
= mGraphicsEfiColors
[Attribute
& 0x0f];
1710 *Background
= mGraphicsEfiColors
[Attribute
>> 4];
1716 Draw Unicode string on the Graphics Console device's screen.
1718 @param This Protocol instance pointer.
1719 @param UnicodeWeight One Unicode string to be displayed.
1720 @param Count The count of Unicode string.
1722 @retval EFI_OUT_OF_RESOURCES If no memory resource to use.
1723 @retval EFI_UNSUPPORTED If no Graphics Output protocol and UGA Draw
1725 @retval EFI_SUCCESS Drawing Unicode string implemented successfully.
1729 DrawUnicodeWeightAtCursorN (
1730 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1731 IN CHAR16
*UnicodeWeight
,
1736 GRAPHICS_CONSOLE_DEV
*Private
;
1737 EFI_IMAGE_OUTPUT
*Blt
;
1739 EFI_FONT_DISPLAY_INFO
*FontInfo
;
1740 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1741 EFI_HII_ROW_INFO
*RowInfoArray
;
1742 UINTN RowInfoArraySize
;
1744 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1745 Blt
= (EFI_IMAGE_OUTPUT
*) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT
));
1747 return EFI_OUT_OF_RESOURCES
;
1750 Blt
->Width
= (UINT16
) (Private
->ModeData
[This
->Mode
->Mode
].GopWidth
);
1751 Blt
->Height
= (UINT16
) (Private
->ModeData
[This
->Mode
->Mode
].GopHeight
);
1753 String
= AllocateCopyPool ((Count
+ 1) * sizeof (CHAR16
), UnicodeWeight
);
1754 if (String
== NULL
) {
1756 return EFI_OUT_OF_RESOURCES
;
1759 // Set the end character
1761 *(String
+ Count
) = L
'\0';
1763 FontInfo
= (EFI_FONT_DISPLAY_INFO
*) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO
));
1764 if (FontInfo
== NULL
) {
1767 return EFI_OUT_OF_RESOURCES
;
1770 // Get current foreground and background colors.
1772 GetTextColors (This
, &FontInfo
->ForegroundColor
, &FontInfo
->BackgroundColor
);
1774 if (Private
->GraphicsOutput
!= NULL
) {
1776 // If Graphics Output protocol exists, using HII Font protocol to draw.
1778 Blt
->Image
.Screen
= Private
->GraphicsOutput
;
1780 Status
= mHiiFont
->StringToImage (
1782 EFI_HII_IGNORE_IF_NO_GLYPH
| EFI_HII_DIRECT_TO_SCREEN
| EFI_HII_IGNORE_LINE_BREAK
,
1786 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1787 This
->Mode
->CursorRow
* EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1793 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1795 // If Graphics Output protocol cannot be found and PcdUgaConsumeSupport enabled,
1796 // using UGA Draw protocol to draw.
1798 ASSERT (Private
->UgaDraw
!= NULL
);
1800 UgaDraw
= Private
->UgaDraw
;
1802 Blt
->Image
.Bitmap
= AllocateZeroPool (Blt
->Width
* Blt
->Height
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
1803 if (Blt
->Image
.Bitmap
== NULL
) {
1806 return EFI_OUT_OF_RESOURCES
;
1809 RowInfoArray
= NULL
;
1811 // StringToImage only support blt'ing image to device using GOP protocol. If GOP is not supported in this platform,
1812 // we ask StringToImage to print the string to blt buffer, then blt to device using UgaDraw.
1814 Status
= mHiiFont
->StringToImage (
1816 EFI_HII_IGNORE_IF_NO_GLYPH
| EFI_HII_IGNORE_LINE_BREAK
,
1820 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1821 This
->Mode
->CursorRow
* EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1827 if (!EFI_ERROR (Status
)) {
1829 // Line breaks are handled by caller of DrawUnicodeWeightAtCursorN, so the updated parameter RowInfoArraySize by StringToImage will
1830 // always be 1 or 0 (if there is no valid Unicode Char can be printed). ASSERT here to make sure.
1832 ASSERT (RowInfoArraySize
<= 1);
1834 Status
= UgaDraw
->Blt (
1836 (EFI_UGA_PIXEL
*) Blt
->Image
.Bitmap
,
1837 EfiUgaBltBufferToVideo
,
1838 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1839 (This
->Mode
->CursorRow
) * EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1840 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1841 (This
->Mode
->CursorRow
) * EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1842 RowInfoArray
[0].LineWidth
,
1843 RowInfoArray
[0].LineHeight
,
1844 Blt
->Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1848 FreePool (RowInfoArray
);
1849 FreePool (Blt
->Image
.Bitmap
);
1851 Status
= EFI_UNSUPPORTED
;
1857 if (String
!= NULL
) {
1860 if (FontInfo
!= NULL
) {
1861 FreePool (FontInfo
);
1867 Flush the cursor on the screen.
1869 If CursorVisible is FALSE, nothing to do and return directly.
1870 If CursorVisible is TRUE,
1871 i) If the cursor shows on screen, it will be erased.
1872 ii) If the cursor does not show on screen, it will be shown.
1874 @param This Protocol instance pointer.
1876 @retval EFI_SUCCESS The cursor is erased successfully.
1881 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
1884 GRAPHICS_CONSOLE_DEV
*Private
;
1885 EFI_SIMPLE_TEXT_OUTPUT_MODE
*CurrentMode
;
1888 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1889 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1890 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground
;
1891 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background
;
1892 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar
[EFI_GLYPH_HEIGHT
][EFI_GLYPH_WIDTH
];
1896 CurrentMode
= This
->Mode
;
1898 if (!CurrentMode
->CursorVisible
) {
1902 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1903 GraphicsOutput
= Private
->GraphicsOutput
;
1904 UgaDraw
= Private
->UgaDraw
;
1907 // In this driver, only narrow character was supported.
1910 // Blt a character to the screen
1912 GlyphX
= (CurrentMode
->CursorColumn
* EFI_GLYPH_WIDTH
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaX
;
1913 GlyphY
= (CurrentMode
->CursorRow
* EFI_GLYPH_HEIGHT
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaY
;
1914 if (GraphicsOutput
!= NULL
) {
1915 GraphicsOutput
->Blt (
1917 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltChar
,
1918 EfiBltVideoToBltBuffer
,
1925 EFI_GLYPH_WIDTH
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1927 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1930 (EFI_UGA_PIXEL
*) (UINTN
) BltChar
,
1931 EfiUgaVideoToBltBuffer
,
1938 EFI_GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)
1942 GetTextColors (This
, &Foreground
.Pixel
, &Background
.Pixel
);
1945 // Convert Monochrome bitmap of the Glyph to BltBuffer structure
1947 for (PosY
= 0; PosY
< EFI_GLYPH_HEIGHT
; PosY
++) {
1948 for (PosX
= 0; PosX
< EFI_GLYPH_WIDTH
; PosX
++) {
1949 if ((mCursorGlyph
.GlyphCol1
[PosY
] & (BIT0
<< PosX
)) != 0) {
1950 BltChar
[PosY
][EFI_GLYPH_WIDTH
- PosX
- 1].Raw
^= Foreground
.Raw
;
1955 if (GraphicsOutput
!= NULL
) {
1956 GraphicsOutput
->Blt (
1958 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltChar
,
1959 EfiBltBufferToVideo
,
1966 EFI_GLYPH_WIDTH
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1968 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1971 (EFI_UGA_PIXEL
*) (UINTN
) BltChar
,
1972 EfiUgaBltBufferToVideo
,
1979 EFI_GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)
1987 HII Database Protocol notification event handler.
1989 Register font package when HII Database Protocol has been installed.
1991 @param[in] Event Event whose notification function is being invoked.
1992 @param[in] Context Pointer to the notification function's context.
1996 RegisterFontPackage (
2002 EFI_HII_SIMPLE_FONT_PACKAGE_HDR
*SimplifiedFont
;
2003 UINT32 PackageLength
;
2006 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
2009 // Locate HII Database Protocol
2011 Status
= gBS
->LocateProtocol (
2012 &gEfiHiiDatabaseProtocolGuid
,
2014 (VOID
**) &HiiDatabase
2016 ASSERT_EFI_ERROR (Status
);
2019 // Add 4 bytes to the header for entire length for HiiAddPackages use only.
2021 // +--------------------------------+ <-- Package
2023 // | PackageLength(4 bytes) |
2025 // |--------------------------------| <-- SimplifiedFont
2027 // |EFI_HII_SIMPLE_FONT_PACKAGE_HDR |
2029 // |--------------------------------| <-- Location
2031 // | gUsStdNarrowGlyphData |
2033 // +--------------------------------+
2035 PackageLength
= sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR
) + mNarrowFontSize
+ 4;
2036 Package
= AllocateZeroPool (PackageLength
);
2037 ASSERT (Package
!= NULL
);
2039 WriteUnaligned32((UINT32
*) Package
,PackageLength
);
2040 SimplifiedFont
= (EFI_HII_SIMPLE_FONT_PACKAGE_HDR
*) (Package
+ 4);
2041 SimplifiedFont
->Header
.Length
= (UINT32
) (PackageLength
- 4);
2042 SimplifiedFont
->Header
.Type
= EFI_HII_PACKAGE_SIMPLE_FONTS
;
2043 SimplifiedFont
->NumberOfNarrowGlyphs
= (UINT16
) (mNarrowFontSize
/ sizeof (EFI_NARROW_GLYPH
));
2045 Location
= (UINT8
*) (&SimplifiedFont
->NumberOfWideGlyphs
+ 1);
2046 CopyMem (Location
, gUsStdNarrowGlyphData
, mNarrowFontSize
);
2049 // Add this simplified font package to a package list then install it.
2051 mHiiHandle
= HiiAddPackages (
2052 &mFontPackageListGuid
,
2057 ASSERT (mHiiHandle
!= NULL
);
2062 The user Entry Point for module GraphicsConsole. The user code starts with this function.
2064 @param[in] ImageHandle The firmware allocated handle for the EFI image.
2065 @param[in] SystemTable A pointer to the EFI System Table.
2067 @retval EFI_SUCCESS The entry point is executed successfully.
2068 @return other Some error occurs when executing this entry point.
2073 InitializeGraphicsConsole (
2074 IN EFI_HANDLE ImageHandle
,
2075 IN EFI_SYSTEM_TABLE
*SystemTable
2081 // Register notify function on HII Database Protocol to add font package.
2083 EfiCreateProtocolNotifyEvent (
2084 &gEfiHiiDatabaseProtocolGuid
,
2086 RegisterFontPackage
,
2092 // Install driver model protocol(s).
2094 Status
= EfiLibInstallDriverBindingComponentName2 (
2097 &gGraphicsConsoleDriverBinding
,
2099 &gGraphicsConsoleComponentName
,
2100 &gGraphicsConsoleComponentName2
2102 ASSERT_EFI_ERROR (Status
);