3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 This is the main routine for initializing the Graphics Console support routines.
23 Add all standard Glyphs from EFI 1.02 Specification
24 Implement optimal automatic Mode creation algorithm
25 Solve palette issues for mixed graphics and text
26 When does this protocol reset the palette?
30 #include "GraphicsConsole.h"
33 // Function Prototypes
37 GraphicsConsoleControllerDriverSupported (
38 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
39 IN EFI_HANDLE Controller
,
40 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
45 GraphicsConsoleControllerDriverStart (
46 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
47 IN EFI_HANDLE Controller
,
48 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
53 GraphicsConsoleControllerDriverStop (
54 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
55 IN EFI_HANDLE Controller
,
56 IN UINTN NumberOfChildren
,
57 IN EFI_HANDLE
*ChildHandleBuffer
62 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
63 OUT EFI_UGA_PIXEL
*Foreground
,
64 OUT EFI_UGA_PIXEL
*Background
68 DrawUnicodeWeightAtCursor (
69 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
70 IN CHAR16 UnicodeWeight
74 DrawUnicodeWeightAtCursorN (
75 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
76 IN CHAR16
*UnicodeWeight
,
82 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
88 GRAPHICS_CONSOLE_DEV mGraphicsConsoleDevTemplate
= {
89 GRAPHICS_CONSOLE_DEV_SIGNATURE
,
90 (EFI_UGA_DRAW_PROTOCOL
*) NULL
,
92 GraphicsConsoleConOutReset
,
93 GraphicsConsoleConOutOutputString
,
94 GraphicsConsoleConOutTestString
,
95 GraphicsConsoleConOutQueryMode
,
96 GraphicsConsoleConOutSetMode
,
97 GraphicsConsoleConOutSetAttribute
,
98 GraphicsConsoleConOutClearScreen
,
99 GraphicsConsoleConOutSetCursorPosition
,
100 GraphicsConsoleConOutEnableCursor
,
101 (EFI_SIMPLE_TEXT_OUTPUT_MODE
*) NULL
106 EFI_TEXT_ATTR(EFI_LIGHTGRAY
, EFI_BLACK
),
112 { 80, 25, 0, 0, 0, 0 }, // Mode 0
113 { 0, 0, 0, 0, 0, 0 }, // Mode 1
114 { 0, 0, 0, 0, 0, 0 } // Mode 2
116 (EFI_UGA_PIXEL
*) NULL
,
120 EFI_HII_PROTOCOL
*mHii
;
122 static CHAR16 mCrLfString
[3] = { CHAR_CARRIAGE_RETURN
, CHAR_LINEFEED
, CHAR_NULL
};
124 static EFI_UGA_PIXEL mEfiColors
[16] = {
128 { 0x00, 0x00, 0x00, 0x00 }, // BLACK
129 { 0x98, 0x00, 0x00, 0x00 }, // BLUE
130 { 0x00, 0x98, 0x00, 0x00 }, // GREEN
131 { 0x98, 0x98, 0x00, 0x00 }, // CYAN
132 { 0x00, 0x00, 0x98, 0x00 }, // RED
133 { 0x98, 0x00, 0x98, 0x00 }, // MAGENTA
134 { 0x00, 0x98, 0x98, 0x00 }, // BROWN
135 { 0x98, 0x98, 0x98, 0x00 }, // LIGHTGRAY
136 { 0x30, 0x30, 0x30, 0x00 }, // DARKGRAY - BRIGHT BLACK
137 { 0xff, 0x00, 0x00, 0x00 }, // LIGHTBLUE - ?
138 { 0x00, 0xff, 0x00, 0x00 }, // LIGHTGREEN - ?
139 { 0xff, 0xff, 0x00, 0x00 }, // LIGHTCYAN
140 { 0x00, 0x00, 0xff, 0x00 }, // LIGHTRED
141 { 0xff, 0x00, 0xff, 0x00 }, // LIGHTMAGENTA
142 { 0x00, 0xff, 0xff, 0x00 }, // LIGHTBROWN
143 { 0xff, 0xff, 0xff, 0x00 } // WHITE
146 static EFI_NARROW_GLYPH mCursorGlyph
= {
149 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF }
152 static CHAR16 SpaceStr
[] = { (CHAR16
)NARROW_CHAR
, ' ', 0 };
155 EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding
= {
156 GraphicsConsoleControllerDriverSupported
,
157 GraphicsConsoleControllerDriverStart
,
158 GraphicsConsoleControllerDriverStop
,
166 GraphicsConsoleControllerDriverSupported (
167 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
168 IN EFI_HANDLE Controller
,
169 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
173 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
174 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
177 // Open the IO Abstraction(s) needed to perform the supported test
179 Status
= gBS
->OpenProtocol (
181 &gEfiUgaDrawProtocolGuid
,
183 This
->DriverBindingHandle
,
185 EFI_OPEN_PROTOCOL_BY_DRIVER
187 if (EFI_ERROR (Status
)) {
191 // We need to ensure that we do not layer on top of a virtual handle.
192 // We need to ensure that the handles produced by the conspliter do not
195 Status
= gBS
->OpenProtocol (
197 &gEfiDevicePathProtocolGuid
,
198 (VOID
**) &DevicePath
,
199 This
->DriverBindingHandle
,
201 EFI_OPEN_PROTOCOL_BY_DRIVER
203 if (!EFI_ERROR (Status
)) {
206 &gEfiDevicePathProtocolGuid
,
207 This
->DriverBindingHandle
,
214 // Does Hii Exist? If not, we aren't ready to run
216 Status
= EfiLocateHiiProtocol ();
219 // Close the I/O Abstraction(s) used to perform the supported test
224 &gEfiUgaDrawProtocolGuid
,
225 This
->DriverBindingHandle
,
234 GraphicsConsoleControllerDriverStart (
235 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
236 IN EFI_HANDLE Controller
,
237 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
243 Start the controller.
247 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
248 Controller - The handle of the controller to start.
249 RemainingDevicePath - A pointer to the remaining portion of a devcie path.
253 EFI_SUCCESS - Return successfully.
254 EFI_OUT_OF_RESOURCES - Out of resources.
259 GRAPHICS_CONSOLE_DEV
*Private
;
260 EFI_HII_PACKAGES
*Package
;
261 EFI_HII_FONT_PACK
*FontPack
;
262 UINTN NarrowFontSize
;
263 UINT32 HorizontalResolution
;
264 UINT32 VerticalResolution
;
272 // Initialize the Graphics Console device instance
274 Private
= AllocateCopyPool (
275 sizeof (GRAPHICS_CONSOLE_DEV
),
276 &mGraphicsConsoleDevTemplate
278 if (Private
== NULL
) {
279 return EFI_OUT_OF_RESOURCES
;
282 Private
->SimpleTextOutput
.Mode
= &(Private
->SimpleTextOutputMode
);
284 Status
= gBS
->OpenProtocol (
286 &gEfiUgaDrawProtocolGuid
,
287 (VOID
**) &Private
->UgaDraw
,
288 This
->DriverBindingHandle
,
290 EFI_OPEN_PROTOCOL_BY_DRIVER
292 if (EFI_ERROR (Status
)) {
296 // Get the HII protocol. If Supported() succeeds, do we really
297 // need to get HII protocol again?
299 Status
= EfiLocateHiiProtocol ();
300 if (EFI_ERROR (Status
)) {
304 NarrowFontSize
= ReturnNarrowFontSize ();
306 FontPack
= AllocateZeroPool (sizeof (EFI_HII_FONT_PACK
) + NarrowFontSize
);
309 FontPack
->Header
.Length
= (UINT32
) (sizeof (EFI_HII_FONT_PACK
) + NarrowFontSize
);
310 FontPack
->Header
.Type
= EFI_HII_FONT
;
311 FontPack
->NumberOfNarrowGlyphs
= (UINT16
) (NarrowFontSize
/ sizeof (EFI_NARROW_GLYPH
));
313 Location
= (UINT8
*) (&FontPack
->NumberOfWideGlyphs
+ sizeof (UINT8
));
314 CopyMem (Location
, UsStdNarrowGlyphData
, NarrowFontSize
);
317 // Register our Fonts into the global database
319 Package
= PreparePackages (1, NULL
, FontPack
);
320 mHii
->NewPack (mHii
, Package
, &(Private
->HiiHandle
));
321 gBS
->FreePool (Package
);
324 // Free the font database
326 gBS
->FreePool (FontPack
);
329 // If the current mode information can not be retrieved, then attemp to set the default mode
330 // of 800x600, 32 bit colot, 60 Hz refresh.
332 HorizontalResolution
= 800;
333 VerticalResolution
= 600;
336 Status
= Private
->UgaDraw
->SetMode (
338 HorizontalResolution
,
343 if (EFI_ERROR (Status
)) {
345 // Get the current mode information from the UGA Draw Protocol
347 Status
= Private
->UgaDraw
->GetMode (
349 &HorizontalResolution
,
354 if (EFI_ERROR (Status
)) {
359 // Compute the maximum number of text Rows and Columns that this current graphics mode can support
361 Columns
= HorizontalResolution
/ GLYPH_WIDTH
;
362 Rows
= VerticalResolution
/ GLYPH_HEIGHT
;
365 // See if the mode is too small to support the required 80x25 text mode
367 if (Columns
< 80 || Rows
< 25) {
371 // Add Mode #0 that must be 80x25
374 Private
->ModeData
[MaxMode
].UgaWidth
= HorizontalResolution
;
375 Private
->ModeData
[MaxMode
].UgaHeight
= VerticalResolution
;
376 Private
->ModeData
[MaxMode
].DeltaX
= (HorizontalResolution
- (80 * GLYPH_WIDTH
)) >> 1;
377 Private
->ModeData
[MaxMode
].DeltaY
= (VerticalResolution
- (25 * GLYPH_HEIGHT
)) >> 1;
381 // If it is possible to support Mode #1 - 80x50, than add it as an active mode
384 Private
->ModeData
[MaxMode
].UgaWidth
= HorizontalResolution
;
385 Private
->ModeData
[MaxMode
].UgaHeight
= VerticalResolution
;
386 Private
->ModeData
[MaxMode
].DeltaX
= (HorizontalResolution
- (80 * GLYPH_WIDTH
)) >> 1;
387 Private
->ModeData
[MaxMode
].DeltaY
= (VerticalResolution
- (50 * GLYPH_HEIGHT
)) >> 1;
391 // If the graphics mode is 800x600, than add a text mode that uses the entire display
393 if (HorizontalResolution
== 800 && VerticalResolution
== 600) {
396 Private
->ModeData
[MaxMode
].Columns
= 0;
397 Private
->ModeData
[MaxMode
].Rows
= 0;
398 Private
->ModeData
[MaxMode
].UgaWidth
= 800;
399 Private
->ModeData
[MaxMode
].UgaHeight
= 600;
400 Private
->ModeData
[MaxMode
].DeltaX
= 0;
401 Private
->ModeData
[MaxMode
].DeltaY
= 0;
405 Private
->ModeData
[MaxMode
].Columns
= 800 / GLYPH_WIDTH
;
406 Private
->ModeData
[MaxMode
].Rows
= 600 / GLYPH_HEIGHT
;
407 Private
->ModeData
[MaxMode
].UgaWidth
= 800;
408 Private
->ModeData
[MaxMode
].UgaHeight
= 600;
409 Private
->ModeData
[MaxMode
].DeltaX
= (800 % GLYPH_WIDTH
) >> 1;
410 Private
->ModeData
[MaxMode
].DeltaY
= (600 % GLYPH_HEIGHT
) >> 1;
414 // Update the maximum number of modes
416 Private
->SimpleTextOutputMode
.MaxMode
= (INT32
) MaxMode
;
419 // Determine the number of text modes that this protocol can support
421 Status
= GraphicsConsoleConOutSetMode (&Private
->SimpleTextOutput
, 0);
422 if (EFI_ERROR (Status
)) {
427 GraphicsConsoleConOutOutputString (&Private
->SimpleTextOutput
, (CHAR16
*)L
"Graphics Console Started\n\r");
431 // Install protocol interfaces for the Graphics Console device.
433 Status
= gBS
->InstallMultipleProtocolInterfaces (
435 &gEfiSimpleTextOutProtocolGuid
,
436 &Private
->SimpleTextOutput
,
441 if (EFI_ERROR (Status
)) {
443 // Close the UGA IO Protocol
447 &gEfiUgaDrawProtocolGuid
,
448 This
->DriverBindingHandle
,
455 if (Private
!= NULL
) {
456 gBS
->FreePool (Private
->LineBuffer
);
457 gBS
->FreePool (Private
);
466 GraphicsConsoleControllerDriverStop (
467 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
468 IN EFI_HANDLE Controller
,
469 IN UINTN NumberOfChildren
,
470 IN EFI_HANDLE
*ChildHandleBuffer
474 EFI_SIMPLE_TEXT_OUT_PROTOCOL
*SimpleTextOutput
;
475 GRAPHICS_CONSOLE_DEV
*Private
;
477 Status
= gBS
->OpenProtocol (
479 &gEfiSimpleTextOutProtocolGuid
,
480 (VOID
**) &SimpleTextOutput
,
481 This
->DriverBindingHandle
,
483 EFI_OPEN_PROTOCOL_GET_PROTOCOL
485 if (EFI_ERROR (Status
)) {
486 return EFI_NOT_STARTED
;
489 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
491 Status
= gBS
->UninstallProtocolInterface (
493 &gEfiSimpleTextOutProtocolGuid
,
494 &Private
->SimpleTextOutput
497 if (!EFI_ERROR (Status
)) {
499 // Close the UGA IO Protocol
503 &gEfiUgaDrawProtocolGuid
,
504 This
->DriverBindingHandle
,
509 // Remove the font pack
511 mHii
->RemovePack (mHii
, Private
->HiiHandle
);
514 // Free our instance data
516 if (Private
!= NULL
) {
517 gBS
->FreePool (Private
->LineBuffer
);
518 gBS
->FreePool (Private
);
526 EfiLocateHiiProtocol (
532 Find if the HII protocol is available. If yes, locate the HII protocol
545 // There should only be one - so buffer size is this
547 Size
= sizeof (EFI_HANDLE
);
549 Status
= gBS
->LocateHandle (
551 &gEfiHiiProtocolGuid
,
557 if (EFI_ERROR (Status
)) {
561 Status
= gBS
->HandleProtocol (
563 &gEfiHiiProtocolGuid
,
570 // Body of the STO functions
574 GraphicsConsoleConOutReset (
575 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
576 IN BOOLEAN ExtendedVerification
581 Implements SIMPLE_TEXT_OUTPUT.Reset().
582 If ExtendeVerification is TRUE, then perform dependent Graphics Console
583 device reset, and set display mode to mode 0.
584 If ExtendedVerification is FALSE, only set display mode to mode 0.
588 This - Indicates the calling context.
590 ExtendedVerification - Indicates that the driver may perform a more exhaustive
591 verification operation of the device during reset.
596 The reset operation succeeds.
599 The Graphics Console is not functioning correctly
603 This
->SetAttribute (This
, EFI_TEXT_ATTR (This
->Mode
->Attribute
& 0x0F, EFI_BACKGROUND_BLACK
));
604 return This
->SetMode (This
, 0);
609 GraphicsConsoleConOutOutputString (
610 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
616 Implements SIMPLE_TEXT_OUTPUT.OutputString().
617 The Unicode string will be converted to Glyphs and will be
618 sent to the Graphics Console.
623 This - Indicates the calling context.
625 WString - The Null-terminated Unicode string to be displayed on
626 the Graphics Console.
631 The string is output successfully.
634 The Graphics Console failed to send the string out.
636 EFI_WARN_UNKNOWN_GLYPH
637 Indicates that some of the characters in the Unicode string could not
638 be rendered and are skipped.
642 GRAPHICS_CONSOLE_DEV
*Private
;
643 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
652 EFI_UGA_PIXEL Foreground
;
653 EFI_UGA_PIXEL Background
;
658 INT32 OriginAttribute
;
663 Mode
= This
->Mode
->Mode
;
664 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
665 UgaDraw
= Private
->UgaDraw
;
667 MaxColumn
= Private
->ModeData
[Mode
].Columns
;
668 MaxRow
= Private
->ModeData
[Mode
].Rows
;
669 DeltaX
= Private
->ModeData
[Mode
].DeltaX
;
670 DeltaY
= Private
->ModeData
[Mode
].DeltaY
;
671 Width
= MaxColumn
* GLYPH_WIDTH
;
672 Height
= (MaxRow
- 1) * GLYPH_HEIGHT
;
673 Delta
= Width
* sizeof (EFI_UGA_PIXEL
);
676 // The Attributes won't change when during the time OutputString is called
678 GetTextColors (This
, &Foreground
, &Background
);
687 OriginAttribute
= This
->Mode
->Attribute
;
691 if (*WString
== CHAR_BACKSPACE
) {
693 // If the cursor is at the left edge of the display, then move the cursor
696 if (This
->Mode
->CursorColumn
== 0 && This
->Mode
->CursorRow
> 0) {
697 This
->Mode
->CursorRow
--;
698 This
->Mode
->CursorColumn
= (INT32
) (MaxColumn
- 1);
699 This
->OutputString (This
, SpaceStr
);
701 This
->Mode
->CursorRow
--;
702 This
->Mode
->CursorColumn
= (INT32
) (MaxColumn
- 1);
703 } else if (This
->Mode
->CursorColumn
> 0) {
705 // If the cursor is not at the left edge of the display, then move the cursor
708 This
->Mode
->CursorColumn
--;
709 This
->OutputString (This
, SpaceStr
);
711 This
->Mode
->CursorColumn
--;
716 } else if (*WString
== CHAR_LINEFEED
) {
718 // If the cursor is at the bottom of the display, then scroll the display one
719 // row, and do not update the cursor position. Otherwise, move the cursor
722 if (This
->Mode
->CursorRow
== (INT32
) (MaxRow
- 1)) {
724 // Scroll Screen Up One Row
731 DeltaY
+ GLYPH_HEIGHT
,
740 // Print Blank Line at last line
756 This
->Mode
->CursorRow
++;
761 } else if (*WString
== CHAR_CARRIAGE_RETURN
) {
763 // Move the cursor to the beginning of the current row.
765 This
->Mode
->CursorColumn
= 0;
768 } else if (*WString
== WIDE_CHAR
) {
770 This
->Mode
->Attribute
|= EFI_WIDE_ATTRIBUTE
;
773 } else if (*WString
== NARROW_CHAR
) {
775 This
->Mode
->Attribute
&= (~ (UINT32
) EFI_WIDE_ATTRIBUTE
);
780 // Print the character at the current cursor position and move the cursor
781 // right one column. If this moves the cursor past the right edge of the
782 // display, then the line should wrap to the beginning of the next line. This
783 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the
784 // bottom of the display, and the line wraps, then the display will be scrolled
786 // If wide char is going to be displayed, need to display one character at a time
787 // Or, need to know the display length of a certain string.
789 // Index is used to determine how many character width units (wide = 2, narrow = 1)
790 // Count is used to determine how many characters are used regardless of their attributes
792 for (Count
= 0, Index
= 0; (This
->Mode
->CursorColumn
+ Index
) < MaxColumn
; Count
++, Index
++) {
793 if (WString
[Count
] == CHAR_NULL
) {
797 if (WString
[Count
] == CHAR_BACKSPACE
) {
801 if (WString
[Count
] == CHAR_LINEFEED
) {
805 if (WString
[Count
] == CHAR_CARRIAGE_RETURN
) {
809 if (WString
[Count
] == WIDE_CHAR
) {
813 if (WString
[Count
] == NARROW_CHAR
) {
817 // Is the wide attribute on?
819 if (This
->Mode
->Attribute
& EFI_WIDE_ATTRIBUTE
) {
821 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop
825 // This is the end-case where if we are at column 79 and about to print a wide character
826 // We should prevent this from happening because we will wrap inappropriately. We should
827 // not print this character until the next line.
829 if ((This
->Mode
->CursorColumn
+ Index
+ 1) > MaxColumn
) {
836 Status
= DrawUnicodeWeightAtCursorN (This
, WString
, Count
);
837 if (EFI_ERROR (Status
)) {
841 // At the end of line, output carriage return and line feed
844 This
->Mode
->CursorColumn
+= (INT32
) Index
;
845 if (This
->Mode
->CursorColumn
> (INT32
) MaxColumn
) {
846 This
->Mode
->CursorColumn
-= 2;
847 This
->OutputString (This
, SpaceStr
);
850 if (This
->Mode
->CursorColumn
>= (INT32
) MaxColumn
) {
852 This
->OutputString (This
, mCrLfString
);
858 This
->Mode
->Attribute
= OriginAttribute
;
863 return EFI_WARN_UNKNOWN_GLYPH
;
871 GraphicsConsoleConOutTestString (
872 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
878 Implements SIMPLE_TEXT_OUTPUT.TestString().
879 If one of the characters in the *Wstring is
880 neither valid valid Unicode drawing characters,
881 not ASCII code, then this function will return
887 This - Indicates the calling context.
889 WString - The Null-terminated Unicode string to be tested.
894 The Graphics Console is capable of rendering the output string.
897 Some of the characters in the Unicode string cannot be rendered.
905 GRAPHICS_CONSOLE_DEV
*Private
;
908 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
912 while (WString
[Count
]) {
913 Status
= mHii
->GetGlyph (
922 if (EFI_ERROR (Status
)) {
923 return EFI_UNSUPPORTED
;
932 GraphicsConsoleConOutQueryMode (
933 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
941 Implements SIMPLE_TEXT_OUTPUT.QueryMode().
942 It returnes information for an available text mode
943 that the Graphics Console supports.
944 In this driver,we only support text mode 80x25, which is
950 This - Indicates the calling context.
952 ModeNumber - The mode number to return information on.
954 Columns - The returned columns of the requested mode.
956 Rows - The returned rows of the requested mode.
961 The requested mode information is returned.
964 The mode number is not valid.
968 GRAPHICS_CONSOLE_DEV
*Private
;
970 if (ModeNumber
>= (UINTN
) This
->Mode
->MaxMode
) {
971 return EFI_UNSUPPORTED
;
974 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
976 *Columns
= Private
->ModeData
[ModeNumber
].Columns
;
977 *Rows
= Private
->ModeData
[ModeNumber
].Rows
;
979 if (*Columns
<= 0 && *Rows
<= 0) {
980 return EFI_UNSUPPORTED
;
989 GraphicsConsoleConOutSetMode (
990 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
996 Implements SIMPLE_TEXT_OUTPUT.SetMode().
997 Set the Graphics Console to a specified mode.
998 In this driver, we only support mode 0.
1002 This - Indicates the calling context.
1004 ModeNumber - The text mode to set.
1009 The requested text mode is set.
1012 The requested text mode cannot be set because of Graphics Console device error.
1015 The text mode number is not valid.
1020 GRAPHICS_CONSOLE_DEV
*Private
;
1021 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1022 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1023 EFI_UGA_PIXEL
*NewLineBuffer
;
1024 UINT32 HorizontalResolution
;
1025 UINT32 VerticalResolution
;
1029 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1030 UgaDraw
= Private
->UgaDraw
;
1031 ModeData
= &(Private
->ModeData
[ModeNumber
]);
1034 // Make sure the requested mode number is supported
1036 if (ModeNumber
>= (UINTN
) This
->Mode
->MaxMode
) {
1037 return EFI_UNSUPPORTED
;
1040 if (ModeData
->Columns
<= 0 && ModeData
->Rows
<= 0) {
1041 return EFI_UNSUPPORTED
;
1044 // Attempt to allocate a line buffer for the requested mode number
1046 Status
= gBS
->AllocatePool (
1047 EfiBootServicesData
,
1048 sizeof (EFI_UGA_PIXEL
) * ModeData
->Columns
* GLYPH_WIDTH
* GLYPH_HEIGHT
,
1049 (VOID
**) &NewLineBuffer
1051 if (EFI_ERROR (Status
)) {
1053 // The new line buffer could not be allocated, so return an error.
1054 // No changes to the state of the current console have been made, so the current console is still valid
1059 // If the mode has been set at least one other time, then LineBuffer will not be NULL
1061 if (Private
->LineBuffer
!= NULL
) {
1063 // Clear the current text window on the current graphics console
1065 This
->ClearScreen (This
);
1068 // If the new mode is the same as the old mode, then just return EFI_SUCCESS
1070 if ((INT32
) ModeNumber
== This
->Mode
->Mode
) {
1071 gBS
->FreePool (NewLineBuffer
);
1075 // Otherwise, the size of the text console and/or the UGA mode will be changed,
1076 // so turn off the cursor, and free the LineBuffer for the current mode
1078 This
->EnableCursor (This
, FALSE
);
1080 gBS
->FreePool (Private
->LineBuffer
);
1083 // Assign the current line buffer to the newly allocated line buffer
1085 Private
->LineBuffer
= NewLineBuffer
;
1088 // Get the current UGA Draw mode information
1090 Status
= UgaDraw
->GetMode (
1092 &HorizontalResolution
,
1093 &VerticalResolution
,
1097 if (EFI_ERROR (Status
) || HorizontalResolution
!= ModeData
->UgaWidth
|| VerticalResolution
!= ModeData
->UgaHeight
) {
1099 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new grapghics mode
1101 Status
= UgaDraw
->SetMode (
1104 ModeData
->UgaHeight
,
1108 if (EFI_ERROR (Status
)) {
1110 // The mode set operation failed
1116 // The current graphics mode is correct, so simply clear the entire display
1118 Status
= UgaDraw
->Blt (
1127 ModeData
->UgaHeight
,
1132 // The new mode is valid, so commit the mode change
1134 This
->Mode
->Mode
= (INT32
) ModeNumber
;
1137 // Move the text cursor to the upper left hand corner of the displat and enable it
1139 This
->SetCursorPosition (This
, 0, 0);
1140 This
->EnableCursor (This
, TRUE
);
1147 GraphicsConsoleConOutSetAttribute (
1148 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1152 Routine Description:
1154 Implements SIMPLE_TEXT_OUTPUT.SetAttribute().
1158 This - Indicates the calling context.
1160 Attrubute - The attribute to set. Only bit0..6 are valid, all other bits
1161 are undefined and must be zero.
1166 The requested attribute is set.
1169 The requested attribute cannot be set due to Graphics Console port error.
1172 The attribute requested is not defined by EFI spec.
1176 if ((Attribute
| 0xFF) != 0xFF) {
1177 return EFI_UNSUPPORTED
;
1180 if ((INT32
) Attribute
== This
->Mode
->Attribute
) {
1186 This
->Mode
->Attribute
= (INT32
) Attribute
;
1195 GraphicsConsoleConOutClearScreen (
1196 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
1199 Routine Description:
1201 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().
1202 It clears the Graphics Console's display to the
1203 currently selected background color.
1208 This - Indicates the calling context.
1213 The operation completed successfully.
1216 The Graphics Console cannot be cleared due to Graphics Console device error.
1219 The Graphics Console is not in a valid text mode.
1224 GRAPHICS_CONSOLE_DEV
*Private
;
1225 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1226 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1227 EFI_UGA_PIXEL Foreground
;
1228 EFI_UGA_PIXEL Background
;
1230 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1231 UgaDraw
= Private
->UgaDraw
;
1232 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1234 GetTextColors (This
, &Foreground
, &Background
);
1236 Status
= UgaDraw
->Blt (
1245 ModeData
->UgaHeight
,
1249 This
->Mode
->CursorColumn
= 0;
1250 This
->Mode
->CursorRow
= 0;
1259 GraphicsConsoleConOutSetCursorPosition (
1260 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1265 Routine Description:
1267 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().
1271 This - Indicates the calling context.
1273 Column - The row to set cursor to.
1275 Row - The column to set cursor to.
1280 The operation completed successfully.
1283 The request fails due to Graphics Console device error.
1286 The Graphics Console is not in a valid text mode, or the cursor position
1287 is invalid for current mode.
1291 GRAPHICS_CONSOLE_DEV
*Private
;
1292 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1294 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1295 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1297 if ((Column
>= ModeData
->Columns
) || (Row
>= ModeData
->Rows
)) {
1298 return EFI_UNSUPPORTED
;
1301 if (((INT32
) Column
== This
->Mode
->CursorColumn
) && ((INT32
) Row
== This
->Mode
->CursorRow
)) {
1307 This
->Mode
->CursorColumn
= (INT32
) Column
;
1308 This
->Mode
->CursorRow
= (INT32
) Row
;
1317 GraphicsConsoleConOutEnableCursor (
1318 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1322 Routine Description:
1324 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
1325 In this driver, the cursor cannot be hidden.
1329 This - Indicates the calling context.
1331 Visible - If TRUE, the cursor is set to be visible,
1332 If FALSE, the cursor is set to be invisible.
1337 The request is valid.
1340 The Graphics Console does not support a hidden cursor.
1346 This
->Mode
->CursorVisible
= Visible
;
1355 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1356 OUT EFI_UGA_PIXEL
*Foreground
,
1357 OUT EFI_UGA_PIXEL
*Background
1362 Attribute
= This
->Mode
->Attribute
& 0x7F;
1364 *Foreground
= mEfiColors
[Attribute
& 0x0f];
1365 *Background
= mEfiColors
[Attribute
>> 4];
1371 DrawUnicodeWeightAtCursorN (
1372 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1373 IN CHAR16
*UnicodeWeight
,
1377 GRAPHICS_CONSOLE_DEV
*Private
;
1379 EFI_STATUS ReturnStatus
;
1381 GLYPH_UNION GlyphData
;
1384 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1385 EFI_UGA_PIXEL Foreground
;
1386 EFI_UGA_PIXEL Background
;
1393 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1395 ReturnStatus
= EFI_SUCCESS
;
1399 GetTextColors (This
, &Foreground
, &Background
);
1403 while (Index
< Count
) {
1404 if (This
->Mode
->Attribute
& EFI_WIDE_ATTRIBUTE
) {
1405 GlyphStatus
= WIDE_CHAR
;
1407 GlyphStatus
= NARROW_CHAR
;
1410 Status
= mHii
->GetGlyph (
1418 if (EFI_ERROR (Status
)) {
1419 ReturnStatus
= Status
;
1424 CopyMem (&GlyphData
, Glyph
, sizeof (GLYPH_UNION
));
1428 // We are creating the second half of the wide character's BLT buffer
1430 if (GlyphWidth
== 0x10 && Counts
== 1) {
1431 CopyMem (&GlyphData
.NarrowGlyph
.GlyphCol1
, &Glyph
->WideGlyph
.GlyphCol2
, sizeof (Glyph
->WideGlyph
.GlyphCol2
));
1436 if (GlyphWidth
== 0x10) {
1439 (UINT8
*) &GlyphData
,
1445 &Private
->LineBuffer
[ArrayIndex
* GLYPH_WIDTH
]
1450 (UINT8
*) &GlyphData
,
1456 &Private
->LineBuffer
[ArrayIndex
* GLYPH_WIDTH
]
1462 } while (Counts
< 2 && GlyphWidth
== 0x10);
1466 // If we are printing Wide characters, treat the BLT as if it is twice as many characters
1468 if (GlyphWidth
== 0x10) {
1472 // Blt a character to the screen
1474 GlyphX
= This
->Mode
->CursorColumn
* GLYPH_WIDTH
;
1475 GlyphY
= This
->Mode
->CursorRow
* GLYPH_HEIGHT
;
1476 UgaDraw
= Private
->UgaDraw
;
1479 Private
->LineBuffer
,
1480 EfiUgaBltBufferToVideo
,
1483 GlyphX
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1484 GlyphY
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1485 GLYPH_WIDTH
* Count
,
1487 GLYPH_WIDTH
* Count
* sizeof (EFI_UGA_PIXEL
)
1490 return ReturnStatus
;
1495 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
1498 GRAPHICS_CONSOLE_DEV
*Private
;
1499 EFI_SIMPLE_TEXT_OUTPUT_MODE
*CurrentMode
;
1502 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1503 EFI_UGA_PIXEL_UNION Foreground
;
1504 EFI_UGA_PIXEL_UNION Background
;
1505 EFI_UGA_PIXEL_UNION BltChar
[GLYPH_HEIGHT
][GLYPH_WIDTH
];
1509 CurrentMode
= This
->Mode
;
1511 if (!CurrentMode
->CursorVisible
) {
1515 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1516 UgaDraw
= Private
->UgaDraw
;
1519 // BUGBUG - we need to think about what to do with wide and narrow character deletions.
1522 // Blt a character to the screen
1524 GlyphX
= (CurrentMode
->CursorColumn
* GLYPH_WIDTH
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaX
;
1525 GlyphY
= (CurrentMode
->CursorRow
* GLYPH_HEIGHT
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaY
;
1528 (EFI_UGA_PIXEL
*) BltChar
,
1529 EfiUgaVideoToBltBuffer
,
1536 GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)
1539 GetTextColors (This
, &Foreground
.Pixel
, &Background
.Pixel
);
1542 // Convert Monochrome bitmap of the Glyph to BltBuffer structure
1544 for (Y
= 0; Y
< GLYPH_HEIGHT
; Y
++) {
1545 for (X
= 0; X
< GLYPH_WIDTH
; X
++) {
1546 if ((mCursorGlyph
.GlyphCol1
[Y
] & (1 << X
)) != 0) {
1547 BltChar
[Y
][GLYPH_WIDTH
- X
- 1].Raw
^= Foreground
.Raw
;
1554 (EFI_UGA_PIXEL
*) BltChar
,
1555 EfiUgaBltBufferToVideo
,
1562 GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)