2 This is the main routine for initializing the Graphics Console support routines.
4 Copyright (c) 2006 - 2010, 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
),
45 { 80, 25, 0, 0, 0, 0 }, // Mode 0
46 { 80, 50, 0, 0, 0, 0 }, // Mode 1
47 { 100,31, 0, 0, 0, 0 }, // Mode 2
48 { 0, 0, 0, 0, 0, 0 } // Mode 3
50 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) NULL
53 EFI_HII_DATABASE_PROTOCOL
*mHiiDatabase
;
54 EFI_HII_FONT_PROTOCOL
*mHiiFont
;
55 EFI_HII_HANDLE mHiiHandle
;
56 EFI_EVENT mHiiRegistration
;
58 EFI_GUID mFontPackageListGuid
= {0xf5f219d3, 0x7006, 0x4648, {0xac, 0x8d, 0xd6, 0x1d, 0xfb, 0x7b, 0xc6, 0xad}};
60 CHAR16 mCrLfString
[3] = { CHAR_CARRIAGE_RETURN
, CHAR_LINEFEED
, CHAR_NULL
};
62 EFI_GRAPHICS_OUTPUT_BLT_PIXEL mGraphicsEfiColors
[16] = {
66 {0x00, 0x00, 0x00, 0x00}, // BLACK
67 {0x98, 0x00, 0x00, 0x00}, // LIGHTBLUE
68 {0x00, 0x98, 0x00, 0x00}, // LIGHGREEN
69 {0x98, 0x98, 0x00, 0x00}, // LIGHCYAN
70 {0x00, 0x00, 0x98, 0x00}, // LIGHRED
71 {0x98, 0x00, 0x98, 0x00}, // MAGENTA
72 {0x00, 0x98, 0x98, 0x00}, // BROWN
73 {0x98, 0x98, 0x98, 0x00}, // LIGHTGRAY
74 {0x30, 0x30, 0x30, 0x00}, // DARKGRAY - BRIGHT BLACK
75 {0xff, 0x00, 0x00, 0x00}, // BLUE
76 {0x00, 0xff, 0x00, 0x00}, // LIME
77 {0xff, 0xff, 0x00, 0x00}, // CYAN
78 {0x00, 0x00, 0xff, 0x00}, // RED
79 {0xff, 0x00, 0xff, 0x00}, // FUCHSIA
80 {0x00, 0xff, 0xff, 0x00}, // YELLOW
81 {0xff, 0xff, 0xff, 0x00} // WHITE
84 EFI_NARROW_GLYPH mCursorGlyph
= {
87 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF }
90 CHAR16 SpaceStr
[] = { NARROW_CHAR
, ' ', 0 };
92 EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding
= {
93 GraphicsConsoleControllerDriverSupported
,
94 GraphicsConsoleControllerDriverStart
,
95 GraphicsConsoleControllerDriverStop
,
102 Test to see if Graphics Console could be supported on the Controller.
104 Graphics Console could be supported if Graphics Output Protocol or UGA Draw
105 Protocol exists on the Controller. (UGA Draw Protocol could be skipped
106 if PcdUgaConsumeSupport is set to FALSE.)
108 @param This Protocol instance pointer.
109 @param Controller Handle of device to test.
110 @param RemainingDevicePath Optional parameter use to pick a specific child
113 @retval EFI_SUCCESS This driver supports this device.
114 @retval other This driver does not support this device.
119 GraphicsConsoleControllerDriverSupported (
120 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
121 IN EFI_HANDLE Controller
,
122 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
126 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
127 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
128 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
130 GraphicsOutput
= NULL
;
133 // Open the IO Abstraction(s) needed to perform the supported test
135 Status
= gBS
->OpenProtocol (
137 &gEfiGraphicsOutputProtocolGuid
,
138 (VOID
**) &GraphicsOutput
,
139 This
->DriverBindingHandle
,
141 EFI_OPEN_PROTOCOL_BY_DRIVER
144 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
146 // Open Graphics Output Protocol failed, try to open UGA Draw Protocol
148 Status
= gBS
->OpenProtocol (
150 &gEfiUgaDrawProtocolGuid
,
152 This
->DriverBindingHandle
,
154 EFI_OPEN_PROTOCOL_BY_DRIVER
157 if (EFI_ERROR (Status
)) {
162 // We need to ensure that we do not layer on top of a virtual handle.
163 // We need to ensure that the handles produced by the conspliter do not
166 Status
= gBS
->OpenProtocol (
168 &gEfiDevicePathProtocolGuid
,
169 (VOID
**) &DevicePath
,
170 This
->DriverBindingHandle
,
172 EFI_OPEN_PROTOCOL_BY_DRIVER
174 if (!EFI_ERROR (Status
)) {
177 &gEfiDevicePathProtocolGuid
,
178 This
->DriverBindingHandle
,
186 // Does Hii Exist? If not, we aren't ready to run
188 Status
= EfiLocateHiiProtocol ();
191 // Close the I/O Abstraction(s) used to perform the supported test
194 if (GraphicsOutput
!= NULL
) {
197 &gEfiGraphicsOutputProtocolGuid
,
198 This
->DriverBindingHandle
,
201 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
204 &gEfiUgaDrawProtocolGuid
,
205 This
->DriverBindingHandle
,
214 Start this driver on Controller by opening Graphics Output protocol or
215 UGA Draw protocol, and installing Simple Text Out protocol on Controller.
216 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)
218 @param This Protocol instance pointer.
219 @param Controller Handle of device to bind driver to
220 @param RemainingDevicePath Optional parameter use to pick a specific child
223 @retval EFI_SUCCESS This driver is added to Controller.
224 @retval other This driver does not support this device.
229 GraphicsConsoleControllerDriverStart (
230 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
231 IN EFI_HANDLE Controller
,
232 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
236 GRAPHICS_CONSOLE_DEV
*Private
;
237 UINT32 HorizontalResolution
;
238 UINT32 VerticalResolution
;
245 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
*Mode
;
249 // Initialize the Graphics Console device instance
251 Private
= AllocateCopyPool (
252 sizeof (GRAPHICS_CONSOLE_DEV
),
253 &mGraphicsConsoleDevTemplate
255 if (Private
== NULL
) {
256 return EFI_OUT_OF_RESOURCES
;
259 Private
->SimpleTextOutput
.Mode
= &(Private
->SimpleTextOutputMode
);
261 Status
= gBS
->OpenProtocol (
263 &gEfiGraphicsOutputProtocolGuid
,
264 (VOID
**) &Private
->GraphicsOutput
,
265 This
->DriverBindingHandle
,
267 EFI_OPEN_PROTOCOL_BY_DRIVER
270 if (EFI_ERROR(Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
271 Status
= gBS
->OpenProtocol (
273 &gEfiUgaDrawProtocolGuid
,
274 (VOID
**) &Private
->UgaDraw
,
275 This
->DriverBindingHandle
,
277 EFI_OPEN_PROTOCOL_BY_DRIVER
281 if (EFI_ERROR (Status
)) {
286 // If the current mode information can not be retrieved, then attempt to set the default mode
287 // of 800x600, 32 bit color, 60 Hz refresh.
289 HorizontalResolution
= 800;
290 VerticalResolution
= 600;
292 if (Private
->GraphicsOutput
!= NULL
) {
294 // The console is build on top of Graphics Output Protocol, find the mode number
295 // for the user-defined mode; if there are multiple video devices,
296 // graphic console driver will set all the video devices to the same mode.
298 Status
= CheckModeSupported (
299 Private
->GraphicsOutput
,
300 CURRENT_HORIZONTAL_RESOLUTION
,
301 CURRENT_VERTICAL_RESOLUTION
,
304 if (!EFI_ERROR(Status
)) {
306 // Update default mode to current mode
308 HorizontalResolution
= CURRENT_HORIZONTAL_RESOLUTION
;
309 VerticalResolution
= CURRENT_VERTICAL_RESOLUTION
;
312 // if not supporting current mode, try 800x600 which is required by UEFI/EFI spec
314 Status
= CheckModeSupported (
315 Private
->GraphicsOutput
,
322 Mode
= Private
->GraphicsOutput
->Mode
;
324 if (EFI_ERROR (Status
) || (Mode
->MaxMode
!= 0)) {
326 // Set default mode failed or device don't support default mode, then get the current mode information
328 HorizontalResolution
= Mode
->Info
->HorizontalResolution
;
329 VerticalResolution
= Mode
->Info
->VerticalResolution
;
330 ModeNumber
= Mode
->Mode
;
332 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
334 // At first try to set user-defined resolution
338 Status
= Private
->UgaDraw
->SetMode (
340 CURRENT_HORIZONTAL_RESOLUTION
,
341 CURRENT_VERTICAL_RESOLUTION
,
345 if (!EFI_ERROR (Status
)) {
346 HorizontalResolution
= CURRENT_HORIZONTAL_RESOLUTION
;
347 VerticalResolution
= CURRENT_VERTICAL_RESOLUTION
;
348 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
350 // Try to set 800*600 which is required by UEFI/EFI spec
352 Status
= Private
->UgaDraw
->SetMode (
354 HorizontalResolution
,
359 if (EFI_ERROR (Status
)) {
360 Status
= Private
->UgaDraw
->GetMode (
362 &HorizontalResolution
,
367 if (EFI_ERROR (Status
)) {
372 Status
= EFI_UNSUPPORTED
;
378 // Compute the maximum number of text Rows and Columns that this current graphics mode can support
380 Columns
= HorizontalResolution
/ EFI_GLYPH_WIDTH
;
381 Rows
= VerticalResolution
/ EFI_GLYPH_HEIGHT
;
384 // See if the mode is too small to support the required 80x25 text mode
386 if (Columns
< 80 || Rows
< 25) {
390 // Add Mode #0 that must be 80x25
393 Private
->ModeData
[MaxMode
].GopWidth
= HorizontalResolution
;
394 Private
->ModeData
[MaxMode
].GopHeight
= VerticalResolution
;
395 Private
->ModeData
[MaxMode
].GopModeNumber
= ModeNumber
;
396 Private
->ModeData
[MaxMode
].DeltaX
= (HorizontalResolution
- (80 * EFI_GLYPH_WIDTH
)) >> 1;
397 Private
->ModeData
[MaxMode
].DeltaY
= (VerticalResolution
- (25 * EFI_GLYPH_HEIGHT
)) >> 1;
401 // If it is possible to support Mode #1 - 80x50, than add it as an active mode
404 Private
->ModeData
[MaxMode
].GopWidth
= HorizontalResolution
;
405 Private
->ModeData
[MaxMode
].GopHeight
= VerticalResolution
;
406 Private
->ModeData
[MaxMode
].GopModeNumber
= ModeNumber
;
407 Private
->ModeData
[MaxMode
].DeltaX
= (HorizontalResolution
- (80 * EFI_GLYPH_WIDTH
)) >> 1;
408 Private
->ModeData
[MaxMode
].DeltaY
= (VerticalResolution
- (50 * EFI_GLYPH_HEIGHT
)) >> 1;
413 // If it is not to support Mode #1 - 80x50, then skip it
416 Private
->ModeData
[MaxMode
].Columns
= 0;
417 Private
->ModeData
[MaxMode
].Rows
= 0;
418 Private
->ModeData
[MaxMode
].GopWidth
= HorizontalResolution
;
419 Private
->ModeData
[MaxMode
].GopHeight
= VerticalResolution
;
420 Private
->ModeData
[MaxMode
].GopModeNumber
= ModeNumber
;
421 Private
->ModeData
[MaxMode
].DeltaX
= 0;
422 Private
->ModeData
[MaxMode
].DeltaY
= 0;
427 // Add Mode #2 that must be 100x31 (graphic mode >= 800x600)
429 if (Columns
>= 100 && Rows
>= 31) {
430 Private
->ModeData
[MaxMode
].GopWidth
= HorizontalResolution
;
431 Private
->ModeData
[MaxMode
].GopHeight
= VerticalResolution
;
432 Private
->ModeData
[MaxMode
].GopModeNumber
= ModeNumber
;
433 Private
->ModeData
[MaxMode
].DeltaX
= (HorizontalResolution
- (100 * EFI_GLYPH_WIDTH
)) >> 1;
434 Private
->ModeData
[MaxMode
].DeltaY
= (VerticalResolution
- (31 * EFI_GLYPH_HEIGHT
)) >> 1;
439 // Add Mode #3 that uses the entire display for user-defined mode
441 if (HorizontalResolution
> 800 && VerticalResolution
> 600) {
442 Private
->ModeData
[MaxMode
].Columns
= HorizontalResolution
/EFI_GLYPH_WIDTH
;
443 Private
->ModeData
[MaxMode
].Rows
= VerticalResolution
/EFI_GLYPH_HEIGHT
;
444 Private
->ModeData
[MaxMode
].GopWidth
= HorizontalResolution
;
445 Private
->ModeData
[MaxMode
].GopHeight
= VerticalResolution
;
446 Private
->ModeData
[MaxMode
].GopModeNumber
= ModeNumber
;
447 Private
->ModeData
[MaxMode
].DeltaX
= (HorizontalResolution
% EFI_GLYPH_WIDTH
) >> 1;
448 Private
->ModeData
[MaxMode
].DeltaY
= (VerticalResolution
% EFI_GLYPH_HEIGHT
) >> 1;
453 // Update the maximum number of modes
455 Private
->SimpleTextOutputMode
.MaxMode
= (INT32
) MaxMode
;
458 // Determine the number of text modes that this protocol can support
460 Status
= GraphicsConsoleConOutSetMode (&Private
->SimpleTextOutput
, 0);
461 if (EFI_ERROR (Status
)) {
466 GraphicsConsoleConOutOutputString (&Private
->SimpleTextOutput
, (CHAR16
*)L
"Graphics Console Started\n\r");
470 // Install protocol interfaces for the Graphics Console device.
472 Status
= gBS
->InstallMultipleProtocolInterfaces (
474 &gEfiSimpleTextOutProtocolGuid
,
475 &Private
->SimpleTextOutput
,
480 if (EFI_ERROR (Status
)) {
482 // Close the GOP and UGA Draw Protocol
484 if (Private
->GraphicsOutput
!= NULL
) {
487 &gEfiGraphicsOutputProtocolGuid
,
488 This
->DriverBindingHandle
,
491 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
494 &gEfiUgaDrawProtocolGuid
,
495 This
->DriverBindingHandle
,
500 if (Private
->LineBuffer
!= NULL
) {
501 FreePool (Private
->LineBuffer
);
514 Stop this driver on Controller by removing Simple Text Out protocol
515 and closing the Graphics Output Protocol or UGA Draw protocol on Controller.
516 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)
519 @param This Protocol instance pointer.
520 @param Controller Handle of device to stop driver on
521 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
522 children is zero stop the entire bus driver.
523 @param ChildHandleBuffer List of Child Handles to Stop.
525 @retval EFI_SUCCESS This driver is removed Controller.
526 @retval EFI_NOT_STARTED Simple Text Out protocol could not be found the
528 @retval other This driver was not removed from this device.
533 GraphicsConsoleControllerDriverStop (
534 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
535 IN EFI_HANDLE Controller
,
536 IN UINTN NumberOfChildren
,
537 IN EFI_HANDLE
*ChildHandleBuffer
541 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
542 GRAPHICS_CONSOLE_DEV
*Private
;
544 Status
= gBS
->OpenProtocol (
546 &gEfiSimpleTextOutProtocolGuid
,
547 (VOID
**) &SimpleTextOutput
,
548 This
->DriverBindingHandle
,
550 EFI_OPEN_PROTOCOL_GET_PROTOCOL
552 if (EFI_ERROR (Status
)) {
553 return EFI_NOT_STARTED
;
556 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
558 Status
= gBS
->UninstallProtocolInterface (
560 &gEfiSimpleTextOutProtocolGuid
,
561 &Private
->SimpleTextOutput
564 if (!EFI_ERROR (Status
)) {
566 // Close the GOP or UGA IO Protocol
568 if (Private
->GraphicsOutput
!= NULL
) {
571 &gEfiGraphicsOutputProtocolGuid
,
572 This
->DriverBindingHandle
,
575 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
578 &gEfiUgaDrawProtocolGuid
,
579 This
->DriverBindingHandle
,
584 if (Private
->LineBuffer
!= NULL
) {
585 FreePool (Private
->LineBuffer
);
589 // Free our instance data
598 Check if the current specific mode supported the user defined resolution
599 for the Graphics Console device based on Graphics Output Protocol.
601 If yes, set the graphic devcice's current mode to this specific mode.
603 @param GraphicsOutput Graphics Output Protocol instance pointer.
604 @param HorizontalResolution User defined horizontal resolution
605 @param VerticalResolution User defined vertical resolution.
606 @param CurrentModeNumber Current specific mode to be check.
608 @retval EFI_SUCCESS The mode is supported.
609 @retval EFI_UNSUPPORTED The specific mode is out of range of graphics
611 @retval other The specific mode does not support user defined
612 resolution or failed to set the current mode to the
613 specific mode on graphics device.
618 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
619 IN UINT32 HorizontalResolution
,
620 IN UINT32 VerticalResolution
,
621 OUT UINT32
*CurrentModeNumber
627 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
630 Status
= EFI_SUCCESS
;
631 MaxMode
= GraphicsOutput
->Mode
->MaxMode
;
633 for (ModeNumber
= 0; ModeNumber
< MaxMode
; ModeNumber
++) {
634 Status
= GraphicsOutput
->QueryMode (
640 if (!EFI_ERROR (Status
)) {
641 if ((Info
->HorizontalResolution
== HorizontalResolution
) &&
642 (Info
->VerticalResolution
== VerticalResolution
)) {
643 if ((GraphicsOutput
->Mode
->Info
->HorizontalResolution
== HorizontalResolution
) &&
644 (GraphicsOutput
->Mode
->Info
->VerticalResolution
== VerticalResolution
)) {
646 // If video device has been set to this mode, we do not need to SetMode again
650 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeNumber
);
651 if (!EFI_ERROR (Status
)) {
661 if (ModeNumber
== GraphicsOutput
->Mode
->MaxMode
) {
662 Status
= EFI_UNSUPPORTED
;
665 *CurrentModeNumber
= ModeNumber
;
671 Locate HII Database protocol and HII Font protocol.
673 @retval EFI_SUCCESS HII Database protocol and HII Font protocol
674 are located successfully.
675 @return other Failed to locate HII Database protocol or
680 EfiLocateHiiProtocol (
689 // There should only be one - so buffer size is this
691 Size
= sizeof (EFI_HANDLE
);
693 Status
= gBS
->LocateHandle (
695 &gEfiHiiDatabaseProtocolGuid
,
701 if (EFI_ERROR (Status
)) {
705 Status
= gBS
->HandleProtocol (
707 &gEfiHiiDatabaseProtocolGuid
,
708 (VOID
**) &mHiiDatabase
711 if (EFI_ERROR (Status
)) {
715 Status
= gBS
->HandleProtocol (
717 &gEfiHiiFontProtocolGuid
,
724 // Body of the STO functions
728 Reset the text output device hardware and optionally run diagnostics.
730 Implements SIMPLE_TEXT_OUTPUT.Reset().
731 If ExtendeVerification is TRUE, then perform dependent Graphics Console
732 device reset, and set display mode to mode 0.
733 If ExtendedVerification is FALSE, only set display mode to mode 0.
735 @param This Protocol instance pointer.
736 @param ExtendedVerification Indicates that the driver may perform a more
737 exhaustive verification operation of the device
740 @retval EFI_SUCCESS The text output device was reset.
741 @retval EFI_DEVICE_ERROR The text output device is not functioning correctly and
747 GraphicsConsoleConOutReset (
748 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
749 IN BOOLEAN ExtendedVerification
752 This
->SetAttribute (This
, EFI_TEXT_ATTR (This
->Mode
->Attribute
& 0x0F, EFI_BACKGROUND_BLACK
));
753 return This
->SetMode (This
, 0);
758 Write a Unicode string to the output device.
760 Implements SIMPLE_TEXT_OUTPUT.OutputString().
761 The Unicode string will be converted to Glyphs and will be
762 sent to the Graphics Console.
764 @param This Protocol instance pointer.
765 @param WString The NULL-terminated Unicode string to be displayed
766 on the output device(s). All output devices must
767 also support the Unicode drawing defined in this file.
769 @retval EFI_SUCCESS The string was output to the device.
770 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output
772 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
774 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
775 characters in the Unicode string could not be
776 rendered and were skipped.
781 GraphicsConsoleConOutOutputString (
782 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
786 GRAPHICS_CONSOLE_DEV
*Private
;
787 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
788 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
797 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
798 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
803 INT32 OriginAttribute
;
806 Status
= EFI_SUCCESS
;
808 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
812 Mode
= This
->Mode
->Mode
;
813 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
814 GraphicsOutput
= Private
->GraphicsOutput
;
815 UgaDraw
= Private
->UgaDraw
;
817 MaxColumn
= Private
->ModeData
[Mode
].Columns
;
818 MaxRow
= Private
->ModeData
[Mode
].Rows
;
819 DeltaX
= Private
->ModeData
[Mode
].DeltaX
;
820 DeltaY
= Private
->ModeData
[Mode
].DeltaY
;
821 Width
= MaxColumn
* EFI_GLYPH_WIDTH
;
822 Height
= (MaxRow
- 1) * EFI_GLYPH_HEIGHT
;
823 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
826 // The Attributes won't change when during the time OutputString is called
828 GetTextColors (This
, &Foreground
, &Background
);
837 OriginAttribute
= This
->Mode
->Attribute
;
839 while (*WString
!= L
'\0') {
841 if (*WString
== CHAR_BACKSPACE
) {
843 // If the cursor is at the left edge of the display, then move the cursor
846 if (This
->Mode
->CursorColumn
== 0 && This
->Mode
->CursorRow
> 0) {
847 This
->Mode
->CursorRow
--;
848 This
->Mode
->CursorColumn
= (INT32
) (MaxColumn
- 1);
849 This
->OutputString (This
, SpaceStr
);
851 This
->Mode
->CursorRow
--;
852 This
->Mode
->CursorColumn
= (INT32
) (MaxColumn
- 1);
853 } else if (This
->Mode
->CursorColumn
> 0) {
855 // If the cursor is not at the left edge of the display, then move the cursor
858 This
->Mode
->CursorColumn
--;
859 This
->OutputString (This
, SpaceStr
);
861 This
->Mode
->CursorColumn
--;
866 } else if (*WString
== CHAR_LINEFEED
) {
868 // If the cursor is at the bottom of the display, then scroll the display one
869 // row, and do not update the cursor position. Otherwise, move the cursor
872 if (This
->Mode
->CursorRow
== (INT32
) (MaxRow
- 1)) {
873 if (GraphicsOutput
!= NULL
) {
875 // Scroll Screen Up One Row
877 GraphicsOutput
->Blt (
882 DeltaY
+ EFI_GLYPH_HEIGHT
,
891 // Print Blank Line at last line
893 GraphicsOutput
->Blt (
905 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
907 // Scroll Screen Up One Row
914 DeltaY
+ EFI_GLYPH_HEIGHT
,
923 // Print Blank Line at last line
927 (EFI_UGA_PIXEL
*) (UINTN
) &Background
,
939 This
->Mode
->CursorRow
++;
944 } else if (*WString
== CHAR_CARRIAGE_RETURN
) {
946 // Move the cursor to the beginning of the current row.
948 This
->Mode
->CursorColumn
= 0;
951 } else if (*WString
== WIDE_CHAR
) {
953 This
->Mode
->Attribute
|= EFI_WIDE_ATTRIBUTE
;
956 } else if (*WString
== NARROW_CHAR
) {
958 This
->Mode
->Attribute
&= (~ (UINT32
) EFI_WIDE_ATTRIBUTE
);
963 // Print the character at the current cursor position and move the cursor
964 // right one column. If this moves the cursor past the right edge of the
965 // display, then the line should wrap to the beginning of the next line. This
966 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the
967 // bottom of the display, and the line wraps, then the display will be scrolled
969 // If wide char is going to be displayed, need to display one character at a time
970 // Or, need to know the display length of a certain string.
972 // Index is used to determine how many character width units (wide = 2, narrow = 1)
973 // Count is used to determine how many characters are used regardless of their attributes
975 for (Count
= 0, Index
= 0; (This
->Mode
->CursorColumn
+ Index
) < MaxColumn
; Count
++, Index
++) {
976 if (WString
[Count
] == CHAR_NULL
||
977 WString
[Count
] == CHAR_BACKSPACE
||
978 WString
[Count
] == CHAR_LINEFEED
||
979 WString
[Count
] == CHAR_CARRIAGE_RETURN
||
980 WString
[Count
] == WIDE_CHAR
||
981 WString
[Count
] == NARROW_CHAR
) {
985 // Is the wide attribute on?
987 if ((This
->Mode
->Attribute
& EFI_WIDE_ATTRIBUTE
) != 0) {
989 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop
993 // This is the end-case where if we are at column 79 and about to print a wide character
994 // We should prevent this from happening because we will wrap inappropriately. We should
995 // not print this character until the next line.
997 if ((This
->Mode
->CursorColumn
+ Index
+ 1) > MaxColumn
) {
1004 Status
= DrawUnicodeWeightAtCursorN (This
, WString
, Count
);
1005 if (EFI_ERROR (Status
)) {
1009 // At the end of line, output carriage return and line feed
1012 This
->Mode
->CursorColumn
+= (INT32
) Index
;
1013 if (This
->Mode
->CursorColumn
> (INT32
) MaxColumn
) {
1014 This
->Mode
->CursorColumn
-= 2;
1015 This
->OutputString (This
, SpaceStr
);
1018 if (This
->Mode
->CursorColumn
>= (INT32
) MaxColumn
) {
1020 This
->OutputString (This
, mCrLfString
);
1026 This
->Mode
->Attribute
= OriginAttribute
;
1031 Status
= EFI_WARN_UNKNOWN_GLYPH
;
1034 gBS
->RestoreTPL (OldTpl
);
1040 Verifies that all characters in a Unicode string can be output to the
1043 Implements SIMPLE_TEXT_OUTPUT.TestString().
1044 If one of the characters in the *Wstring is neither valid valid Unicode
1045 drawing characters, not ASCII code, then this function will return
1048 @param This Protocol instance pointer.
1049 @param WString The NULL-terminated Unicode string to be examined for the output
1052 @retval EFI_SUCCESS The device(s) are capable of rendering the output string.
1053 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be
1054 rendered by one or more of the output devices mapped
1060 GraphicsConsoleConOutTestString (
1061 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1068 EFI_IMAGE_OUTPUT
*Blt
;
1073 while (WString
[Count
] != 0) {
1074 Status
= mHiiFont
->GetGlyph (
1087 if (EFI_ERROR (Status
)) {
1088 return EFI_UNSUPPORTED
;
1097 Returns information for an available text mode that the output device(s)
1100 Implements SIMPLE_TEXT_OUTPUT.QueryMode().
1101 It returnes information for an available text mode that the Graphics Console supports.
1102 In this driver,we only support text mode 80x25, which is defined as mode 0.
1104 @param This Protocol instance pointer.
1105 @param ModeNumber The mode number to return information on.
1106 @param Columns The returned columns of the requested mode.
1107 @param Rows The returned rows of the requested mode.
1109 @retval EFI_SUCCESS The requested mode information is returned.
1110 @retval EFI_UNSUPPORTED The mode number is not valid.
1115 GraphicsConsoleConOutQueryMode (
1116 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1117 IN UINTN ModeNumber
,
1122 GRAPHICS_CONSOLE_DEV
*Private
;
1126 if (ModeNumber
>= (UINTN
) This
->Mode
->MaxMode
) {
1127 return EFI_UNSUPPORTED
;
1130 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1131 Status
= EFI_SUCCESS
;
1133 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1135 *Columns
= Private
->ModeData
[ModeNumber
].Columns
;
1136 *Rows
= Private
->ModeData
[ModeNumber
].Rows
;
1138 if (*Columns
<= 0 && *Rows
<= 0) {
1139 Status
= EFI_UNSUPPORTED
;
1145 gBS
->RestoreTPL (OldTpl
);
1151 Sets the output device(s) to a specified mode.
1153 Implements SIMPLE_TEXT_OUTPUT.SetMode().
1154 Set the Graphics Console to a specified mode. In this driver, we only support mode 0.
1156 @param This Protocol instance pointer.
1157 @param ModeNumber The text mode to set.
1159 @retval EFI_SUCCESS The requested text mode is set.
1160 @retval EFI_DEVICE_ERROR The requested text mode cannot be set because of
1161 Graphics Console device error.
1162 @retval EFI_UNSUPPORTED The text mode number is not valid.
1167 GraphicsConsoleConOutSetMode (
1168 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1173 GRAPHICS_CONSOLE_DEV
*Private
;
1174 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1175 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*NewLineBuffer
;
1176 UINT32 HorizontalResolution
;
1177 UINT32 VerticalResolution
;
1178 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1179 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1184 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1186 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1187 GraphicsOutput
= Private
->GraphicsOutput
;
1188 UgaDraw
= Private
->UgaDraw
;
1189 ModeData
= &(Private
->ModeData
[ModeNumber
]);
1191 if (ModeData
->Columns
<= 0 && ModeData
->Rows
<= 0) {
1192 Status
= EFI_UNSUPPORTED
;
1197 // Make sure the requested mode number is supported
1199 if (ModeNumber
>= (UINTN
) This
->Mode
->MaxMode
) {
1200 Status
= EFI_UNSUPPORTED
;
1204 if (ModeData
->Columns
<= 0 && ModeData
->Rows
<= 0) {
1205 Status
= EFI_UNSUPPORTED
;
1209 // Attempt to allocate a line buffer for the requested mode number
1211 NewLineBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * ModeData
->Columns
* EFI_GLYPH_WIDTH
* EFI_GLYPH_HEIGHT
);
1213 if (NewLineBuffer
== NULL
) {
1215 // The new line buffer could not be allocated, so return an error.
1216 // No changes to the state of the current console have been made, so the current console is still valid
1218 Status
= EFI_OUT_OF_RESOURCES
;
1222 // If the mode has been set at least one other time, then LineBuffer will not be NULL
1224 if (Private
->LineBuffer
!= NULL
) {
1226 // Clear the current text window on the current graphics console
1228 This
->ClearScreen (This
);
1231 // If the new mode is the same as the old mode, then just return EFI_SUCCESS
1233 if ((INT32
) ModeNumber
== This
->Mode
->Mode
) {
1234 FreePool (NewLineBuffer
);
1235 Status
= EFI_SUCCESS
;
1239 // Otherwise, the size of the text console and/or the GOP/UGA mode will be changed,
1240 // so erase the cursor, and free the LineBuffer for the current mode
1244 FreePool (Private
->LineBuffer
);
1247 // Assign the current line buffer to the newly allocated line buffer
1249 Private
->LineBuffer
= NewLineBuffer
;
1251 if (GraphicsOutput
!= NULL
) {
1252 if (ModeData
->GopModeNumber
!= GraphicsOutput
->Mode
->Mode
) {
1254 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
1256 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeData
->GopModeNumber
);
1257 if (EFI_ERROR (Status
)) {
1259 // The mode set operation failed
1265 // The current graphics mode is correct, so simply clear the entire display
1267 Status
= GraphicsOutput
->Blt (
1269 &mGraphicsEfiColors
[0],
1276 ModeData
->GopHeight
,
1280 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1282 // Get the current UGA Draw mode information
1284 Status
= UgaDraw
->GetMode (
1286 &HorizontalResolution
,
1287 &VerticalResolution
,
1291 if (EFI_ERROR (Status
) || HorizontalResolution
!= ModeData
->GopWidth
|| VerticalResolution
!= ModeData
->GopHeight
) {
1293 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
1295 Status
= UgaDraw
->SetMode (
1298 ModeData
->GopHeight
,
1302 if (EFI_ERROR (Status
)) {
1304 // The mode set operation failed
1310 // The current graphics mode is correct, so simply clear the entire display
1312 Status
= UgaDraw
->Blt (
1314 (EFI_UGA_PIXEL
*) (UINTN
) &mGraphicsEfiColors
[0],
1321 ModeData
->GopHeight
,
1328 // The new mode is valid, so commit the mode change
1330 This
->Mode
->Mode
= (INT32
) ModeNumber
;
1333 // Move the text cursor to the upper left hand corner of the display and enable it
1335 This
->SetCursorPosition (This
, 0, 0);
1337 Status
= EFI_SUCCESS
;
1340 gBS
->RestoreTPL (OldTpl
);
1346 Sets the background and foreground colors for the OutputString () and
1347 ClearScreen () functions.
1349 Implements SIMPLE_TEXT_OUTPUT.SetAttribute().
1351 @param This Protocol instance pointer.
1352 @param Attribute The attribute to set. Bits 0..3 are the foreground
1353 color, and bits 4..6 are the background color.
1354 All other bits are undefined and must be zero.
1356 @retval EFI_SUCCESS The requested attribute is set.
1357 @retval EFI_DEVICE_ERROR The requested attribute cannot be set due to Graphics Console port error.
1358 @retval EFI_UNSUPPORTED The attribute requested is not defined.
1363 GraphicsConsoleConOutSetAttribute (
1364 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1370 if ((Attribute
| 0xFF) != 0xFF) {
1371 return EFI_UNSUPPORTED
;
1374 if ((INT32
) Attribute
== This
->Mode
->Attribute
) {
1378 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1382 This
->Mode
->Attribute
= (INT32
) Attribute
;
1386 gBS
->RestoreTPL (OldTpl
);
1393 Clears the output device(s) display to the currently selected background
1396 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().
1398 @param This Protocol instance pointer.
1400 @retval EFI_SUCCESS The operation completed successfully.
1401 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
1402 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
1407 GraphicsConsoleConOutClearScreen (
1408 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
1412 GRAPHICS_CONSOLE_DEV
*Private
;
1413 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1414 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1415 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1416 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
1417 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
1420 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1422 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1423 GraphicsOutput
= Private
->GraphicsOutput
;
1424 UgaDraw
= Private
->UgaDraw
;
1425 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1427 GetTextColors (This
, &Foreground
, &Background
);
1428 if (GraphicsOutput
!= NULL
) {
1429 Status
= GraphicsOutput
->Blt (
1438 ModeData
->GopHeight
,
1441 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1442 Status
= UgaDraw
->Blt (
1444 (EFI_UGA_PIXEL
*) (UINTN
) &Background
,
1451 ModeData
->GopHeight
,
1455 Status
= EFI_UNSUPPORTED
;
1458 This
->Mode
->CursorColumn
= 0;
1459 This
->Mode
->CursorRow
= 0;
1463 gBS
->RestoreTPL (OldTpl
);
1470 Sets the current coordinates of the cursor position.
1472 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().
1474 @param This Protocol instance pointer.
1475 @param Column The position to set the cursor to. Must be greater than or
1476 equal to zero and less than the number of columns and rows
1478 @param Row The position to set the cursor to. Must be greater than or
1479 equal to zero and less than the number of columns and rows
1482 @retval EFI_SUCCESS The operation completed successfully.
1483 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
1484 @retval EFI_UNSUPPORTED The output device is not in a valid text mode, or the
1485 cursor position is invalid for the current mode.
1490 GraphicsConsoleConOutSetCursorPosition (
1491 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1496 GRAPHICS_CONSOLE_DEV
*Private
;
1497 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1501 Status
= EFI_SUCCESS
;
1503 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1505 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1506 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1508 if ((Column
>= ModeData
->Columns
) || (Row
>= ModeData
->Rows
)) {
1509 Status
= EFI_UNSUPPORTED
;
1513 if ((This
->Mode
->CursorColumn
== (INT32
) Column
) && (This
->Mode
->CursorRow
== (INT32
) Row
)) {
1514 Status
= EFI_SUCCESS
;
1520 This
->Mode
->CursorColumn
= (INT32
) Column
;
1521 This
->Mode
->CursorRow
= (INT32
) Row
;
1526 gBS
->RestoreTPL (OldTpl
);
1533 Makes the cursor visible or invisible.
1535 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
1537 @param This Protocol instance pointer.
1538 @param Visible If TRUE, the cursor is set to be visible, If FALSE,
1539 the cursor is set to be invisible.
1541 @retval EFI_SUCCESS The operation completed successfully.
1546 GraphicsConsoleConOutEnableCursor (
1547 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1553 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1557 This
->Mode
->CursorVisible
= Visible
;
1561 gBS
->RestoreTPL (OldTpl
);
1566 Gets Graphics Console devcie's foreground color and background color.
1568 @param This Protocol instance pointer.
1569 @param Foreground Returned text foreground color.
1570 @param Background Returned text background color.
1572 @retval EFI_SUCCESS It returned always.
1577 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1578 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Foreground
,
1579 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Background
1584 Attribute
= This
->Mode
->Attribute
& 0x7F;
1586 *Foreground
= mGraphicsEfiColors
[Attribute
& 0x0f];
1587 *Background
= mGraphicsEfiColors
[Attribute
>> 4];
1593 Draw Unicode string on the Graphics Console device's screen.
1595 @param This Protocol instance pointer.
1596 @param UnicodeWeight One Unicode string to be displayed.
1597 @param Count The count of Unicode string.
1599 @retval EFI_OUT_OF_RESOURCES If no memory resource to use.
1600 @retval EFI_UNSUPPORTED If no Graphics Output protocol and UGA Draw
1602 @retval EFI_SUCCESS Drawing Unicode string implemented successfully.
1606 DrawUnicodeWeightAtCursorN (
1607 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
1608 IN CHAR16
*UnicodeWeight
,
1613 GRAPHICS_CONSOLE_DEV
*Private
;
1614 EFI_IMAGE_OUTPUT
*Blt
;
1616 EFI_FONT_DISPLAY_INFO
*FontInfo
;
1617 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1618 EFI_HII_ROW_INFO
*RowInfoArray
;
1619 UINTN RowInfoArraySize
;
1621 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1622 Blt
= (EFI_IMAGE_OUTPUT
*) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT
));
1624 return EFI_OUT_OF_RESOURCES
;
1627 Blt
->Width
= (UINT16
) (Private
->ModeData
[This
->Mode
->Mode
].GopWidth
);
1628 Blt
->Height
= (UINT16
) (Private
->ModeData
[This
->Mode
->Mode
].GopHeight
);
1630 String
= AllocateCopyPool ((Count
+ 1) * sizeof (CHAR16
), UnicodeWeight
);
1631 if (String
== NULL
) {
1633 return EFI_OUT_OF_RESOURCES
;
1636 // Set the end character
1638 *(String
+ Count
) = L
'\0';
1640 FontInfo
= (EFI_FONT_DISPLAY_INFO
*) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO
));
1641 if (FontInfo
== NULL
) {
1644 return EFI_OUT_OF_RESOURCES
;
1647 // Get current foreground and background colors.
1649 GetTextColors (This
, &FontInfo
->ForegroundColor
, &FontInfo
->BackgroundColor
);
1651 if (Private
->GraphicsOutput
!= NULL
) {
1653 // If Graphics Output protocol exists, using HII Font protocol to draw.
1655 Blt
->Image
.Screen
= Private
->GraphicsOutput
;
1657 Status
= mHiiFont
->StringToImage (
1659 EFI_HII_IGNORE_IF_NO_GLYPH
| EFI_HII_DIRECT_TO_SCREEN
| EFI_HII_IGNORE_LINE_BREAK
,
1663 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1664 This
->Mode
->CursorRow
* EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1670 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1672 // If Graphics Output protocol cannot be found and PcdUgaConsumeSupport enabled,
1673 // using UGA Draw protocol to draw.
1675 ASSERT (Private
->UgaDraw
!= NULL
);
1677 UgaDraw
= Private
->UgaDraw
;
1679 Blt
->Image
.Bitmap
= AllocateZeroPool (Blt
->Width
* Blt
->Height
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
1680 if (Blt
->Image
.Bitmap
== NULL
) {
1683 return EFI_OUT_OF_RESOURCES
;
1686 RowInfoArray
= NULL
;
1688 // StringToImage only support blt'ing image to device using GOP protocol. If GOP is not supported in this platform,
1689 // we ask StringToImage to print the string to blt buffer, then blt to device using UgaDraw.
1691 Status
= mHiiFont
->StringToImage (
1693 EFI_HII_IGNORE_IF_NO_GLYPH
| EFI_HII_IGNORE_LINE_BREAK
,
1697 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1698 This
->Mode
->CursorRow
* EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1704 if (!EFI_ERROR (Status
)) {
1706 // Line breaks are handled by caller of DrawUnicodeWeightAtCursorN, so the updated parameter RowInfoArraySize by StringToImage will
1707 // always be 1 or 0 (if there is no valid Unicode Char can be printed). ASSERT here to make sure.
1709 ASSERT (RowInfoArraySize
<= 1);
1711 Status
= UgaDraw
->Blt (
1713 (EFI_UGA_PIXEL
*) Blt
->Image
.Bitmap
,
1714 EfiUgaBltBufferToVideo
,
1715 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1716 (This
->Mode
->CursorRow
) * EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1717 This
->Mode
->CursorColumn
* EFI_GLYPH_WIDTH
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1718 (This
->Mode
->CursorRow
) * EFI_GLYPH_HEIGHT
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1719 RowInfoArray
[0].LineWidth
,
1720 RowInfoArray
[0].LineHeight
,
1721 Blt
->Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1725 FreePool (RowInfoArray
);
1726 FreePool (Blt
->Image
.Bitmap
);
1728 Status
= EFI_UNSUPPORTED
;
1734 if (String
!= NULL
) {
1737 if (FontInfo
!= NULL
) {
1738 FreePool (FontInfo
);
1744 Erase the cursor on the screen.
1746 @param This Protocol instance pointer.
1748 @retval EFI_SUCCESS The cursor is erased successfully.
1753 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
1756 GRAPHICS_CONSOLE_DEV
*Private
;
1757 EFI_SIMPLE_TEXT_OUTPUT_MODE
*CurrentMode
;
1760 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1761 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1762 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground
;
1763 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background
;
1764 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar
[EFI_GLYPH_HEIGHT
][EFI_GLYPH_WIDTH
];
1768 CurrentMode
= This
->Mode
;
1770 if (!CurrentMode
->CursorVisible
) {
1774 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1775 GraphicsOutput
= Private
->GraphicsOutput
;
1776 UgaDraw
= Private
->UgaDraw
;
1779 // In this driver, only narrow character was supported.
1782 // Blt a character to the screen
1784 GlyphX
= (CurrentMode
->CursorColumn
* EFI_GLYPH_WIDTH
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaX
;
1785 GlyphY
= (CurrentMode
->CursorRow
* EFI_GLYPH_HEIGHT
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaY
;
1786 if (GraphicsOutput
!= NULL
) {
1787 GraphicsOutput
->Blt (
1789 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltChar
,
1790 EfiBltVideoToBltBuffer
,
1797 EFI_GLYPH_WIDTH
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1799 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1802 (EFI_UGA_PIXEL
*) (UINTN
) BltChar
,
1803 EfiUgaVideoToBltBuffer
,
1810 EFI_GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)
1814 GetTextColors (This
, &Foreground
.Pixel
, &Background
.Pixel
);
1817 // Convert Monochrome bitmap of the Glyph to BltBuffer structure
1819 for (PosY
= 0; PosY
< EFI_GLYPH_HEIGHT
; PosY
++) {
1820 for (PosX
= 0; PosX
< EFI_GLYPH_WIDTH
; PosX
++) {
1821 if ((mCursorGlyph
.GlyphCol1
[PosY
] & (BIT0
<< PosX
)) != 0) {
1822 BltChar
[PosY
][EFI_GLYPH_WIDTH
- PosX
- 1].Raw
^= Foreground
.Raw
;
1827 if (GraphicsOutput
!= NULL
) {
1828 GraphicsOutput
->Blt (
1830 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltChar
,
1831 EfiBltBufferToVideo
,
1838 EFI_GLYPH_WIDTH
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1840 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
1843 (EFI_UGA_PIXEL
*) (UINTN
) BltChar
,
1844 EfiUgaBltBufferToVideo
,
1851 EFI_GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)
1859 HII Database Protocol notification event handler.
1861 Register font package when HII Database Protocol has been installed.
1863 @param[in] Event Event whose notification function is being invoked.
1864 @param[in] Context Pointer to the notification function's context.
1868 RegisterFontPackage (
1874 EFI_HII_SIMPLE_FONT_PACKAGE_HDR
*SimplifiedFont
;
1875 UINT32 PackageLength
;
1878 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
1881 // Locate HII Database Protocol
1883 Status
= gBS
->LocateProtocol (
1884 &gEfiHiiDatabaseProtocolGuid
,
1886 (VOID
**) &HiiDatabase
1888 ASSERT_EFI_ERROR (Status
);
1891 // Add 4 bytes to the header for entire length for HiiAddPackages use only.
1893 // +--------------------------------+ <-- Package
1895 // | PackageLength(4 bytes) |
1897 // |--------------------------------| <-- SimplifiedFont
1899 // |EFI_HII_SIMPLE_FONT_PACKAGE_HDR |
1901 // |--------------------------------| <-- Location
1903 // | gUsStdNarrowGlyphData |
1905 // +--------------------------------+
1907 PackageLength
= sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR
) + mNarrowFontSize
+ 4;
1908 Package
= AllocateZeroPool (PackageLength
);
1909 ASSERT (Package
!= NULL
);
1911 WriteUnaligned32((UINT32
*) Package
,PackageLength
);
1912 SimplifiedFont
= (EFI_HII_SIMPLE_FONT_PACKAGE_HDR
*) (Package
+ 4);
1913 SimplifiedFont
->Header
.Length
= (UINT32
) (PackageLength
- 4);
1914 SimplifiedFont
->Header
.Type
= EFI_HII_PACKAGE_SIMPLE_FONTS
;
1915 SimplifiedFont
->NumberOfNarrowGlyphs
= (UINT16
) (mNarrowFontSize
/ sizeof (EFI_NARROW_GLYPH
));
1917 Location
= (UINT8
*) (&SimplifiedFont
->NumberOfWideGlyphs
+ 1);
1918 CopyMem (Location
, gUsStdNarrowGlyphData
, mNarrowFontSize
);
1921 // Add this simplified font package to a package list then install it.
1923 mHiiHandle
= HiiAddPackages (
1924 &mFontPackageListGuid
,
1929 ASSERT (mHiiHandle
!= NULL
);
1934 The user Entry Point for module GraphicsConsole. The user code starts with this function.
1936 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1937 @param[in] SystemTable A pointer to the EFI System Table.
1939 @retval EFI_SUCCESS The entry point is executed successfully.
1940 @return other Some error occurs when executing this entry point.
1945 InitializeGraphicsConsole (
1946 IN EFI_HANDLE ImageHandle
,
1947 IN EFI_SYSTEM_TABLE
*SystemTable
1953 // Register notify function on HII Database Protocol to add font package.
1955 EfiCreateProtocolNotifyEvent (
1956 &gEfiHiiDatabaseProtocolGuid
,
1958 RegisterFontPackage
,
1964 // Install driver model protocol(s).
1966 Status
= EfiLibInstallDriverBindingComponentName2 (
1969 &gGraphicsConsoleDriverBinding
,
1971 &gGraphicsConsoleComponentName
,
1972 &gGraphicsConsoleComponentName2
1974 ASSERT_EFI_ERROR (Status
);