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_GRAPHICS_OUTPUT_BLT_PIXEL
*Foreground
,
64 OUT EFI_GRAPHICS_OUTPUT_BLT_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_GRAPHICS_OUTPUT_PROTOCOL
*) NULL
,
91 (EFI_UGA_DRAW_PROTOCOL
*) NULL
,
93 GraphicsConsoleConOutReset
,
94 GraphicsConsoleConOutOutputString
,
95 GraphicsConsoleConOutTestString
,
96 GraphicsConsoleConOutQueryMode
,
97 GraphicsConsoleConOutSetMode
,
98 GraphicsConsoleConOutSetAttribute
,
99 GraphicsConsoleConOutClearScreen
,
100 GraphicsConsoleConOutSetCursorPosition
,
101 GraphicsConsoleConOutEnableCursor
,
102 (EFI_SIMPLE_TEXT_OUTPUT_MODE
*) NULL
107 EFI_TEXT_ATTR(EFI_LIGHTGRAY
, EFI_BLACK
),
113 { 80, 25, 0, 0, 0, 0 }, // Mode 0
114 { 80, 50, 0, 0, 0, 0 }, // Mode 1
115 { 0, 0, 0, 0, 0, 0 } // Mode 2
117 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) NULL
,
121 EFI_HII_PROTOCOL
*mHii
;
123 static CHAR16 mCrLfString
[3] = { CHAR_CARRIAGE_RETURN
, CHAR_LINEFEED
, CHAR_NULL
};
125 static EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors
[16] = {
129 0x00, 0x00, 0x00, 0x00, // BLACK
130 0x98, 0x00, 0x00, 0x00, // BLUE
131 0x00, 0x98, 0x00, 0x00, // GREEN
132 0x98, 0x98, 0x00, 0x00, // CYAN
133 0x00, 0x00, 0x98, 0x00, // RED
134 0x98, 0x00, 0x98, 0x00, // MAGENTA
135 0x00, 0x98, 0x98, 0x00, // BROWN
136 0x98, 0x98, 0x98, 0x00, // LIGHTGRAY
137 0x30, 0x30, 0x30, 0x00, // DARKGRAY - BRIGHT BLACK
138 0xff, 0x00, 0x00, 0x00, // LIGHTBLUE - ?
139 0x00, 0xff, 0x00, 0x00, // LIGHTGREEN - ?
140 0xff, 0xff, 0x00, 0x00, // LIGHTCYAN
141 0x00, 0x00, 0xff, 0x00, // LIGHTRED
142 0xff, 0x00, 0xff, 0x00, // LIGHTMAGENTA
143 0x00, 0xff, 0xff, 0x00, // LIGHTBROWN
144 0xff, 0xff, 0xff, 0x00, // WHITE
147 static EFI_NARROW_GLYPH mCursorGlyph
= {
150 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF }
153 EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding
= {
154 GraphicsConsoleControllerDriverSupported
,
155 GraphicsConsoleControllerDriverStart
,
156 GraphicsConsoleControllerDriverStop
,
164 GraphicsConsoleControllerDriverSupported (
165 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
166 IN EFI_HANDLE Controller
,
167 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
171 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
172 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
173 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
177 // Open the IO Abstraction(s) needed to perform the supported test
179 Status
= gBS
->OpenProtocol (
181 &gEfiGraphicsOutputProtocolGuid
,
182 (VOID
**) &GraphicsOutput
,
183 This
->DriverBindingHandle
,
185 EFI_OPEN_PROTOCOL_BY_DRIVER
188 if (EFI_ERROR (Status
)) {
189 GraphicsOutput
= NULL
;
191 // Open Graphics Output Protocol failed, try to open UGA Draw Protocol
193 Status
= gBS
->OpenProtocol (
195 &gEfiUgaDrawProtocolGuid
,
197 This
->DriverBindingHandle
,
199 EFI_OPEN_PROTOCOL_BY_DRIVER
201 if (EFI_ERROR (Status
)) {
207 // We need to ensure that we do not layer on top of a virtual handle.
208 // We need to ensure that the handles produced by the conspliter do not
211 Status
= gBS
->OpenProtocol (
213 &gEfiDevicePathProtocolGuid
,
214 (VOID
**) &DevicePath
,
215 This
->DriverBindingHandle
,
217 EFI_OPEN_PROTOCOL_BY_DRIVER
219 if (!EFI_ERROR (Status
)) {
222 &gEfiDevicePathProtocolGuid
,
223 This
->DriverBindingHandle
,
230 // Does Hii Exist? If not, we aren't ready to run
232 Status
= EfiLocateHiiProtocol ();
235 // Close the I/O Abstraction(s) used to perform the supported test
238 if (GraphicsOutput
!= NULL
) {
241 &gEfiGraphicsOutputProtocolGuid
,
242 This
->DriverBindingHandle
,
248 &gEfiUgaDrawProtocolGuid
,
249 This
->DriverBindingHandle
,
258 GraphicsConsoleControllerDriverStart (
259 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
260 IN EFI_HANDLE Controller
,
261 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
267 Start the controller.
271 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
272 Controller - The handle of the controller to start.
273 RemainingDevicePath - A pointer to the remaining portion of a devcie path.
277 EFI_SUCCESS - Return successfully.
278 EFI_OUT_OF_RESOURCES - Out of resources.
283 GRAPHICS_CONSOLE_DEV
*Private
;
284 EFI_HII_PACKAGES
*Package
;
285 EFI_HII_FONT_PACK
*FontPack
;
286 UINTN NarrowFontSize
;
287 UINT32 HorizontalResolution
;
288 UINT32 VerticalResolution
;
297 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
302 // Initialize the Graphics Console device instance
304 Private
= AllocateCopyPool (
305 sizeof (GRAPHICS_CONSOLE_DEV
),
306 &mGraphicsConsoleDevTemplate
308 if (Private
== NULL
) {
309 return EFI_OUT_OF_RESOURCES
;
312 Private
->SimpleTextOutput
.Mode
= &(Private
->SimpleTextOutputMode
);
314 Status
= gBS
->OpenProtocol (
316 &gEfiGraphicsOutputProtocolGuid
,
317 (VOID
**) &Private
->GraphicsOutput
,
318 This
->DriverBindingHandle
,
320 EFI_OPEN_PROTOCOL_BY_DRIVER
322 if (EFI_ERROR(Status
)) {
323 Private
->GraphicsOutput
= NULL
;
325 Status
= gBS
->OpenProtocol (
327 &gEfiUgaDrawProtocolGuid
,
328 (VOID
**) &Private
->UgaDraw
,
329 This
->DriverBindingHandle
,
331 EFI_OPEN_PROTOCOL_BY_DRIVER
333 if (EFI_ERROR (Status
)) {
339 // Get the HII protocol. If Supported() succeeds, do we really
340 // need to get HII protocol again?
342 Status
= EfiLocateHiiProtocol ();
343 if (EFI_ERROR (Status
)) {
347 NarrowFontSize
= ReturnNarrowFontSize ();
349 FontPack
= AllocateZeroPool (sizeof (EFI_HII_FONT_PACK
) + NarrowFontSize
);
352 FontPack
->Header
.Length
= (UINT32
) (sizeof (EFI_HII_FONT_PACK
) + NarrowFontSize
);
353 FontPack
->Header
.Type
= EFI_HII_FONT
;
354 FontPack
->NumberOfNarrowGlyphs
= (UINT16
) (NarrowFontSize
/ sizeof (EFI_NARROW_GLYPH
));
356 Location
= (UINT8
*) (&FontPack
->NumberOfWideGlyphs
+ sizeof (UINT8
));
357 CopyMem (Location
, UsStdNarrowGlyphData
, NarrowFontSize
);
360 // Register our Fonts into the global database
362 Package
= PreparePackages (1, NULL
, FontPack
);
363 mHii
->NewPack (mHii
, Package
, &(Private
->HiiHandle
));
364 gBS
->FreePool (Package
);
367 // Free the font database
369 gBS
->FreePool (FontPack
);
372 // If the current mode information can not be retrieved, then attemp to set the default mode
373 // of 800x600, 32 bit colot, 60 Hz refresh.
375 HorizontalResolution
= 800;
376 VerticalResolution
= 600;
378 if (Private
->GraphicsOutput
!= NULL
) {
380 // The console is build on top of Graphics Output Protocol, find the mode number for 800x600
382 for (ModeNumber
= 0; ModeNumber
< Private
->GraphicsOutput
->Mode
->MaxMode
; ModeNumber
++) {
383 Status
= Private
->GraphicsOutput
->QueryMode (
384 Private
->GraphicsOutput
,
389 if (!EFI_ERROR (Status
)) {
390 if ((Info
->HorizontalResolution
== 800) &&
391 (Info
->VerticalResolution
== 600) &&
392 ((Info
->PixelFormat
== PixelRedGreenBlueReserved8BitPerColor
) ||
393 (Info
->PixelFormat
== PixelBlueGreenRedReserved8BitPerColor
))) {
394 Status
= Private
->GraphicsOutput
->SetMode (Private
->GraphicsOutput
, ModeNumber
);
395 if (!EFI_ERROR (Status
)) {
396 gBS
->FreePool (Info
);
400 gBS
->FreePool (Info
);
404 if (EFI_ERROR (Status
) || (ModeNumber
== Private
->GraphicsOutput
->Mode
->MaxMode
)) {
406 // Set default mode failed or device don't support default mode, then get the current mode information
408 HorizontalResolution
= Private
->GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
409 VerticalResolution
= Private
->GraphicsOutput
->Mode
->Info
->VerticalResolution
;
410 ModeNumber
= Private
->GraphicsOutput
->Mode
->Mode
;
414 // The console is build on top of UGA Draw Protocol
418 Status
= Private
->UgaDraw
->SetMode (
420 HorizontalResolution
,
425 if (EFI_ERROR (Status
)) {
427 // Get the current mode information from the UGA Draw Protocol
429 Status
= Private
->UgaDraw
->GetMode (
431 &HorizontalResolution
,
436 if (EFI_ERROR (Status
)) {
443 // Compute the maximum number of text Rows and Columns that this current graphics mode can support
445 Columns
= HorizontalResolution
/ GLYPH_WIDTH
;
446 Rows
= VerticalResolution
/ GLYPH_HEIGHT
;
449 // See if the mode is too small to support the required 80x25 text mode
451 if (Columns
< 80 || Rows
< 25) {
455 // Add Mode #0 that must be 80x25
458 Private
->ModeData
[MaxMode
].GopWidth
= HorizontalResolution
;
459 Private
->ModeData
[MaxMode
].GopHeight
= VerticalResolution
;
460 Private
->ModeData
[MaxMode
].GopModeNumber
= ModeNumber
;
461 Private
->ModeData
[MaxMode
].DeltaX
= (HorizontalResolution
- (80 * GLYPH_WIDTH
)) >> 1;
462 Private
->ModeData
[MaxMode
].DeltaY
= (VerticalResolution
- (25 * GLYPH_HEIGHT
)) >> 1;
466 // If it is possible to support Mode #1 - 80x50, than add it as an active mode
469 Private
->ModeData
[MaxMode
].GopWidth
= HorizontalResolution
;
470 Private
->ModeData
[MaxMode
].GopHeight
= VerticalResolution
;
471 Private
->ModeData
[MaxMode
].GopModeNumber
= ModeNumber
;
472 Private
->ModeData
[MaxMode
].DeltaX
= (HorizontalResolution
- (80 * GLYPH_WIDTH
)) >> 1;
473 Private
->ModeData
[MaxMode
].DeltaY
= (VerticalResolution
- (50 * GLYPH_HEIGHT
)) >> 1;
477 // If the graphics mode is 800x600, than add a text mode that uses the entire display
479 if (HorizontalResolution
== 800 && VerticalResolution
== 600) {
482 Private
->ModeData
[MaxMode
].Columns
= 0;
483 Private
->ModeData
[MaxMode
].Rows
= 0;
484 Private
->ModeData
[MaxMode
].GopWidth
= 800;
485 Private
->ModeData
[MaxMode
].GopHeight
= 600;
486 Private
->ModeData
[MaxMode
].GopModeNumber
= ModeNumber
;
487 Private
->ModeData
[MaxMode
].DeltaX
= 0;
488 Private
->ModeData
[MaxMode
].DeltaY
= 0;
492 Private
->ModeData
[MaxMode
].Columns
= 800 / GLYPH_WIDTH
;
493 Private
->ModeData
[MaxMode
].Rows
= 600 / GLYPH_HEIGHT
;
494 Private
->ModeData
[MaxMode
].GopWidth
= 800;
495 Private
->ModeData
[MaxMode
].GopHeight
= 600;
496 Private
->ModeData
[MaxMode
].GopModeNumber
= ModeNumber
;
497 Private
->ModeData
[MaxMode
].DeltaX
= (800 % GLYPH_WIDTH
) >> 1;
498 Private
->ModeData
[MaxMode
].DeltaY
= (600 % GLYPH_HEIGHT
) >> 1;
502 // Update the maximum number of modes
504 Private
->SimpleTextOutputMode
.MaxMode
= (INT32
) MaxMode
;
507 // Determine the number of text modes that this protocol can support
509 Status
= GraphicsConsoleConOutSetMode (&Private
->SimpleTextOutput
, 0);
510 if (EFI_ERROR (Status
)) {
515 GraphicsConsoleConOutOutputString (&Private
->SimpleTextOutput
, (CHAR16
*)L
"Graphics Console Started\n\r");
519 // Install protocol interfaces for the Graphics Console device.
521 Status
= gBS
->InstallMultipleProtocolInterfaces (
523 &gEfiSimpleTextOutProtocolGuid
,
524 &Private
->SimpleTextOutput
,
529 if (EFI_ERROR (Status
)) {
531 // Close the GOP or UGA IO Protocol
533 if (Private
->GraphicsOutput
!= NULL
) {
536 &gEfiGraphicsOutputProtocolGuid
,
537 This
->DriverBindingHandle
,
543 &gEfiUgaDrawProtocolGuid
,
544 This
->DriverBindingHandle
,
552 if (Private
!= NULL
) {
553 gBS
->FreePool (Private
->LineBuffer
);
554 gBS
->FreePool (Private
);
563 GraphicsConsoleControllerDriverStop (
564 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
565 IN EFI_HANDLE Controller
,
566 IN UINTN NumberOfChildren
,
567 IN EFI_HANDLE
*ChildHandleBuffer
571 EFI_SIMPLE_TEXT_OUT_PROTOCOL
*SimpleTextOutput
;
572 GRAPHICS_CONSOLE_DEV
*Private
;
574 Status
= gBS
->OpenProtocol (
576 &gEfiSimpleTextOutProtocolGuid
,
577 (VOID
**) &SimpleTextOutput
,
578 This
->DriverBindingHandle
,
580 EFI_OPEN_PROTOCOL_GET_PROTOCOL
582 if (EFI_ERROR (Status
)) {
583 return EFI_NOT_STARTED
;
586 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
588 Status
= gBS
->UninstallProtocolInterface (
590 &gEfiSimpleTextOutProtocolGuid
,
591 &Private
->SimpleTextOutput
594 if (!EFI_ERROR (Status
)) {
596 // Close the GOP or UGA IO Protocol
598 if (Private
->GraphicsOutput
!= NULL
) {
601 &gEfiGraphicsOutputProtocolGuid
,
602 This
->DriverBindingHandle
,
608 &gEfiUgaDrawProtocolGuid
,
609 This
->DriverBindingHandle
,
615 // Remove the font pack
617 mHii
->RemovePack (mHii
, Private
->HiiHandle
);
620 // Free our instance data
622 if (Private
!= NULL
) {
623 gBS
->FreePool (Private
->LineBuffer
);
624 gBS
->FreePool (Private
);
632 EfiLocateHiiProtocol (
638 Find if the HII protocol is available. If yes, locate the HII protocol
651 // There should only be one - so buffer size is this
653 Size
= sizeof (EFI_HANDLE
);
655 Status
= gBS
->LocateHandle (
657 &gEfiHiiProtocolGuid
,
663 if (EFI_ERROR (Status
)) {
667 Status
= gBS
->HandleProtocol (
669 &gEfiHiiProtocolGuid
,
676 // Body of the STO functions
680 GraphicsConsoleConOutReset (
681 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
682 IN BOOLEAN ExtendedVerification
687 Implements SIMPLE_TEXT_OUTPUT.Reset().
688 If ExtendeVerification is TRUE, then perform dependent Graphics Console
689 device reset, and set display mode to mode 0.
690 If ExtendedVerification is FALSE, only set display mode to mode 0.
694 This - Indicates the calling context.
696 ExtendedVerification - Indicates that the driver may perform a more exhaustive
697 verification operation of the device during reset.
702 The reset operation succeeds.
705 The Graphics Console is not functioning correctly
709 This
->SetAttribute (This
, EFI_TEXT_ATTR (This
->Mode
->Attribute
& 0x0F, EFI_BACKGROUND_BLACK
));
710 return This
->SetMode (This
, 0);
715 GraphicsConsoleConOutOutputString (
716 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
722 Implements SIMPLE_TEXT_OUTPUT.OutputString().
723 The Unicode string will be converted to Glyphs and will be
724 sent to the Graphics Console.
729 This - Indicates the calling context.
731 WString - The Null-terminated Unicode string to be displayed on
732 the Graphics Console.
737 The string is output successfully.
740 The Graphics Console failed to send the string out.
742 EFI_WARN_UNKNOWN_GLYPH
743 Indicates that some of the characters in the Unicode string could not
744 be rendered and are skipped.
748 GRAPHICS_CONSOLE_DEV
*Private
;
749 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
750 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
759 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
760 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
765 INT32 OriginAttribute
;
766 CHAR16 SpaceStr
[] = { NARROW_CHAR
, ' ', 0 };
771 Mode
= This
->Mode
->Mode
;
772 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
773 GraphicsOutput
= Private
->GraphicsOutput
;
774 UgaDraw
= Private
->UgaDraw
;
776 MaxColumn
= Private
->ModeData
[Mode
].Columns
;
777 MaxRow
= Private
->ModeData
[Mode
].Rows
;
778 DeltaX
= Private
->ModeData
[Mode
].DeltaX
;
779 DeltaY
= Private
->ModeData
[Mode
].DeltaY
;
780 Width
= MaxColumn
* GLYPH_WIDTH
;
781 Height
= (MaxRow
- 1) * GLYPH_HEIGHT
;
782 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
785 // The Attributes won't change when during the time OutputString is called
787 GetTextColors (This
, &Foreground
, &Background
);
796 OriginAttribute
= This
->Mode
->Attribute
;
800 if (*WString
== CHAR_BACKSPACE
) {
802 // If the cursor is at the left edge of the display, then move the cursor
805 if (This
->Mode
->CursorColumn
== 0 && This
->Mode
->CursorRow
> 0) {
806 This
->Mode
->CursorRow
--;
807 This
->Mode
->CursorColumn
= (INT32
) (MaxColumn
- 1);
808 This
->OutputString (This
, SpaceStr
);
810 This
->Mode
->CursorRow
--;
811 This
->Mode
->CursorColumn
= (INT32
) (MaxColumn
- 1);
812 } else if (This
->Mode
->CursorColumn
> 0) {
814 // If the cursor is not at the left edge of the display, then move the cursor
817 This
->Mode
->CursorColumn
--;
818 This
->OutputString (This
, SpaceStr
);
820 This
->Mode
->CursorColumn
--;
825 } else if (*WString
== CHAR_LINEFEED
) {
827 // If the cursor is at the bottom of the display, then scroll the display one
828 // row, and do not update the cursor position. Otherwise, move the cursor
831 if (This
->Mode
->CursorRow
== (INT32
) (MaxRow
- 1)) {
832 if (GraphicsOutput
!= NULL
) {
834 // Scroll Screen Up One Row
836 GraphicsOutput
->Blt (
841 DeltaY
+ GLYPH_HEIGHT
,
850 // Print Blank Line at last line
852 GraphicsOutput
->Blt (
866 // Scroll Screen Up One Row
873 DeltaY
+ GLYPH_HEIGHT
,
882 // Print Blank Line at last line
886 (EFI_UGA_PIXEL
*) (UINTN
) &Background
,
898 This
->Mode
->CursorRow
++;
903 } else if (*WString
== CHAR_CARRIAGE_RETURN
) {
905 // Move the cursor to the beginning of the current row.
907 This
->Mode
->CursorColumn
= 0;
910 } else if (*WString
== WIDE_CHAR
) {
912 This
->Mode
->Attribute
|= EFI_WIDE_ATTRIBUTE
;
915 } else if (*WString
== NARROW_CHAR
) {
917 This
->Mode
->Attribute
&= (~ (UINT32
) EFI_WIDE_ATTRIBUTE
);
922 // Print the character at the current cursor position and move the cursor
923 // right one column. If this moves the cursor past the right edge of the
924 // display, then the line should wrap to the beginning of the next line. This
925 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the
926 // bottom of the display, and the line wraps, then the display will be scrolled
928 // If wide char is going to be displayed, need to display one character at a time
929 // Or, need to know the display length of a certain string.
931 // Index is used to determine how many character width units (wide = 2, narrow = 1)
932 // Count is used to determine how many characters are used regardless of their attributes
934 for (Count
= 0, Index
= 0; (This
->Mode
->CursorColumn
+ Index
) < MaxColumn
; Count
++, Index
++) {
935 if (WString
[Count
] == CHAR_NULL
) {
939 if (WString
[Count
] == CHAR_BACKSPACE
) {
943 if (WString
[Count
] == CHAR_LINEFEED
) {
947 if (WString
[Count
] == CHAR_CARRIAGE_RETURN
) {
951 if (WString
[Count
] == WIDE_CHAR
) {
955 if (WString
[Count
] == NARROW_CHAR
) {
959 // Is the wide attribute on?
961 if (This
->Mode
->Attribute
& EFI_WIDE_ATTRIBUTE
) {
963 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop
967 // This is the end-case where if we are at column 79 and about to print a wide character
968 // We should prevent this from happening because we will wrap inappropriately. We should
969 // not print this character until the next line.
971 if ((This
->Mode
->CursorColumn
+ Index
+ 1) > MaxColumn
) {
978 Status
= DrawUnicodeWeightAtCursorN (This
, WString
, Count
);
979 if (EFI_ERROR (Status
)) {
983 // At the end of line, output carriage return and line feed
986 This
->Mode
->CursorColumn
+= (INT32
) Index
;
987 if (This
->Mode
->CursorColumn
> (INT32
) MaxColumn
) {
988 This
->Mode
->CursorColumn
-= 2;
989 This
->OutputString (This
, SpaceStr
);
992 if (This
->Mode
->CursorColumn
>= (INT32
) MaxColumn
) {
994 This
->OutputString (This
, mCrLfString
);
1000 This
->Mode
->Attribute
= OriginAttribute
;
1005 return EFI_WARN_UNKNOWN_GLYPH
;
1013 GraphicsConsoleConOutTestString (
1014 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1018 Routine Description:
1020 Implements SIMPLE_TEXT_OUTPUT.TestString().
1021 If one of the characters in the *Wstring is
1022 neither valid valid Unicode drawing characters,
1023 not ASCII code, then this function will return
1029 This - Indicates the calling context.
1031 WString - The Null-terminated Unicode string to be tested.
1036 The Graphics Console is capable of rendering the output string.
1039 Some of the characters in the Unicode string cannot be rendered.
1047 GRAPHICS_CONSOLE_DEV
*Private
;
1050 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1054 while (WString
[Count
]) {
1055 Status
= mHii
->GetGlyph (
1064 if (EFI_ERROR (Status
)) {
1065 return EFI_UNSUPPORTED
;
1074 GraphicsConsoleConOutQueryMode (
1075 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1076 IN UINTN ModeNumber
,
1081 Routine Description:
1083 Implements SIMPLE_TEXT_OUTPUT.QueryMode().
1084 It returnes information for an available text mode
1085 that the Graphics Console supports.
1086 In this driver,we only support text mode 80x25, which is
1092 This - Indicates the calling context.
1094 ModeNumber - The mode number to return information on.
1096 Columns - The returned columns of the requested mode.
1098 Rows - The returned rows of the requested mode.
1103 The requested mode information is returned.
1106 The mode number is not valid.
1110 GRAPHICS_CONSOLE_DEV
*Private
;
1112 if (ModeNumber
>= (UINTN
) This
->Mode
->MaxMode
) {
1113 return EFI_UNSUPPORTED
;
1116 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1118 *Columns
= Private
->ModeData
[ModeNumber
].Columns
;
1119 *Rows
= Private
->ModeData
[ModeNumber
].Rows
;
1121 if (*Columns
<= 0 && *Rows
<= 0) {
1122 return EFI_UNSUPPORTED
;
1131 GraphicsConsoleConOutSetMode (
1132 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1136 Routine Description:
1138 Implements SIMPLE_TEXT_OUTPUT.SetMode().
1139 Set the Graphics Console to a specified mode.
1140 In this driver, we only support mode 0.
1144 This - Indicates the calling context.
1146 ModeNumber - The text mode to set.
1151 The requested text mode is set.
1154 The requested text mode cannot be set because of Graphics Console device error.
1157 The text mode number is not valid.
1162 GRAPHICS_CONSOLE_DEV
*Private
;
1163 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1164 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*NewLineBuffer
;
1165 UINT32 HorizontalResolution
;
1166 UINT32 VerticalResolution
;
1167 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1168 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1172 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1173 GraphicsOutput
= Private
->GraphicsOutput
;
1174 UgaDraw
= Private
->UgaDraw
;
1175 ModeData
= &(Private
->ModeData
[ModeNumber
]);
1178 // Make sure the requested mode number is supported
1180 if (ModeNumber
>= (UINTN
) This
->Mode
->MaxMode
) {
1181 return EFI_UNSUPPORTED
;
1184 if (ModeData
->Columns
<= 0 && ModeData
->Rows
<= 0) {
1185 return EFI_UNSUPPORTED
;
1188 // Attempt to allocate a line buffer for the requested mode number
1190 Status
= gBS
->AllocatePool (
1191 EfiBootServicesData
,
1192 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * ModeData
->Columns
* GLYPH_WIDTH
* GLYPH_HEIGHT
,
1193 (VOID
**) &NewLineBuffer
1195 if (EFI_ERROR (Status
)) {
1197 // The new line buffer could not be allocated, so return an error.
1198 // No changes to the state of the current console have been made, so the current console is still valid
1203 // If the mode has been set at least one other time, then LineBuffer will not be NULL
1205 if (Private
->LineBuffer
!= NULL
) {
1207 // Clear the current text window on the current graphics console
1209 This
->ClearScreen (This
);
1212 // If the new mode is the same as the old mode, then just return EFI_SUCCESS
1214 if ((INT32
) ModeNumber
== This
->Mode
->Mode
) {
1215 gBS
->FreePool (NewLineBuffer
);
1219 // Otherwise, the size of the text console and/or the UGA mode will be changed,
1220 // so turn off the cursor, and free the LineBuffer for the current mode
1222 This
->EnableCursor (This
, FALSE
);
1224 gBS
->FreePool (Private
->LineBuffer
);
1227 // Assign the current line buffer to the newly allocated line buffer
1229 Private
->LineBuffer
= NewLineBuffer
;
1231 if (GraphicsOutput
!= NULL
) {
1232 if (ModeData
->GopModeNumber
!= GraphicsOutput
->Mode
->Mode
) {
1234 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new grapghics mode
1236 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeData
->GopModeNumber
);
1237 if (EFI_ERROR (Status
)) {
1239 // The mode set operation failed
1245 // The current graphics mode is correct, so simply clear the entire display
1247 Status
= GraphicsOutput
->Blt (
1256 ModeData
->GopHeight
,
1262 // Get the current UGA Draw mode information
1264 Status
= UgaDraw
->GetMode (
1266 &HorizontalResolution
,
1267 &VerticalResolution
,
1271 if (EFI_ERROR (Status
) || HorizontalResolution
!= ModeData
->GopWidth
|| VerticalResolution
!= ModeData
->GopHeight
) {
1273 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new grapghics mode
1275 Status
= UgaDraw
->SetMode (
1278 ModeData
->GopHeight
,
1282 if (EFI_ERROR (Status
)) {
1284 // The mode set operation failed
1290 // The current graphics mode is correct, so simply clear the entire display
1292 Status
= UgaDraw
->Blt (
1294 (EFI_UGA_PIXEL
*) (UINTN
) &mEfiColors
[0],
1301 ModeData
->GopHeight
,
1308 // The new mode is valid, so commit the mode change
1310 This
->Mode
->Mode
= (INT32
) ModeNumber
;
1313 // Move the text cursor to the upper left hand corner of the displat and enable it
1315 This
->SetCursorPosition (This
, 0, 0);
1316 This
->EnableCursor (This
, TRUE
);
1323 GraphicsConsoleConOutSetAttribute (
1324 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1328 Routine Description:
1330 Implements SIMPLE_TEXT_OUTPUT.SetAttribute().
1334 This - Indicates the calling context.
1336 Attrubute - The attribute to set. Only bit0..6 are valid, all other bits
1337 are undefined and must be zero.
1342 The requested attribute is set.
1345 The requested attribute cannot be set due to Graphics Console port error.
1348 The attribute requested is not defined by EFI spec.
1352 if ((Attribute
| 0xFF) != 0xFF) {
1353 return EFI_UNSUPPORTED
;
1356 if ((INT32
) Attribute
== This
->Mode
->Attribute
) {
1362 This
->Mode
->Attribute
= (INT32
) Attribute
;
1371 GraphicsConsoleConOutClearScreen (
1372 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
1375 Routine Description:
1377 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().
1378 It clears the Graphics Console's display to the
1379 currently selected background color.
1384 This - Indicates the calling context.
1389 The operation completed successfully.
1392 The Graphics Console cannot be cleared due to Graphics Console device error.
1395 The Graphics Console is not in a valid text mode.
1400 GRAPHICS_CONSOLE_DEV
*Private
;
1401 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1402 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1403 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1404 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
1405 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
1407 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1408 GraphicsOutput
= Private
->GraphicsOutput
;
1409 UgaDraw
= Private
->UgaDraw
;
1410 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1412 GetTextColors (This
, &Foreground
, &Background
);
1413 if (GraphicsOutput
!= NULL
) {
1414 Status
= GraphicsOutput
->Blt (
1423 ModeData
->GopHeight
,
1427 Status
= UgaDraw
->Blt (
1429 (EFI_UGA_PIXEL
*) (UINTN
) &Background
,
1436 ModeData
->GopHeight
,
1441 This
->Mode
->CursorColumn
= 0;
1442 This
->Mode
->CursorRow
= 0;
1451 GraphicsConsoleConOutSetCursorPosition (
1452 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1457 Routine Description:
1459 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().
1463 This - Indicates the calling context.
1465 Column - The row to set cursor to.
1467 Row - The column to set cursor to.
1472 The operation completed successfully.
1475 The request fails due to Graphics Console device error.
1478 The Graphics Console is not in a valid text mode, or the cursor position
1479 is invalid for current mode.
1483 GRAPHICS_CONSOLE_DEV
*Private
;
1484 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1486 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1487 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1489 if ((Column
>= ModeData
->Columns
) || (Row
>= ModeData
->Rows
)) {
1490 return EFI_UNSUPPORTED
;
1493 if (((INT32
) Column
== This
->Mode
->CursorColumn
) && ((INT32
) Row
== This
->Mode
->CursorRow
)) {
1499 This
->Mode
->CursorColumn
= (INT32
) Column
;
1500 This
->Mode
->CursorRow
= (INT32
) Row
;
1509 GraphicsConsoleConOutEnableCursor (
1510 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1514 Routine Description:
1516 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
1517 In this driver, the cursor cannot be hidden.
1521 This - Indicates the calling context.
1523 Visible - If TRUE, the cursor is set to be visible,
1524 If FALSE, the cursor is set to be invisible.
1529 The request is valid.
1532 The Graphics Console does not support a hidden cursor.
1538 This
->Mode
->CursorVisible
= Visible
;
1547 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1548 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Foreground
,
1549 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Background
1554 Attribute
= This
->Mode
->Attribute
& 0x7F;
1556 *Foreground
= mEfiColors
[Attribute
& 0x0f];
1557 *Background
= mEfiColors
[Attribute
>> 4];
1563 DrawUnicodeWeightAtCursorN (
1564 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1565 IN CHAR16
*UnicodeWeight
,
1569 GRAPHICS_CONSOLE_DEV
*Private
;
1571 EFI_STATUS ReturnStatus
;
1573 GLYPH_UNION GlyphData
;
1576 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1577 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1578 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
1579 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
1586 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1588 ReturnStatus
= EFI_SUCCESS
;
1592 GetTextColors (This
, &Foreground
, &Background
);
1596 while (Index
< Count
) {
1597 if (This
->Mode
->Attribute
& EFI_WIDE_ATTRIBUTE
) {
1598 GlyphStatus
= WIDE_CHAR
;
1600 GlyphStatus
= NARROW_CHAR
;
1603 Status
= mHii
->GetGlyph (
1611 if (EFI_ERROR (Status
)) {
1612 ReturnStatus
= Status
;
1617 CopyMem (&GlyphData
, Glyph
, sizeof (GLYPH_UNION
));
1621 // We are creating the second half of the wide character's BLT buffer
1623 if (GlyphWidth
== 0x10 && Counts
== 1) {
1624 CopyMem (&GlyphData
.NarrowGlyph
.GlyphCol1
, &Glyph
->WideGlyph
.GlyphCol2
, sizeof (Glyph
->WideGlyph
.GlyphCol2
));
1629 if (GlyphWidth
== 0x10) {
1632 (UINT8
*) &GlyphData
,
1638 &Private
->LineBuffer
[ArrayIndex
* GLYPH_WIDTH
]
1643 (UINT8
*) &GlyphData
,
1649 &Private
->LineBuffer
[ArrayIndex
* GLYPH_WIDTH
]
1655 } while (Counts
< 2 && GlyphWidth
== 0x10);
1659 // If we are printing Wide characters, treat the BLT as if it is twice as many characters
1661 if (GlyphWidth
== 0x10) {
1665 // Blt a character to the screen
1667 GlyphX
= This
->Mode
->CursorColumn
* GLYPH_WIDTH
;
1668 GlyphY
= This
->Mode
->CursorRow
* GLYPH_HEIGHT
;
1669 GraphicsOutput
= Private
->GraphicsOutput
;
1670 UgaDraw
= Private
->UgaDraw
;
1671 if (GraphicsOutput
!= NULL
) {
1672 GraphicsOutput
->Blt (
1674 Private
->LineBuffer
,
1675 EfiBltBufferToVideo
,
1678 GlyphX
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1679 GlyphY
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1680 GLYPH_WIDTH
* Count
,
1682 GLYPH_WIDTH
* Count
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1687 (EFI_UGA_PIXEL
*) (UINTN
) Private
->LineBuffer
,
1688 EfiUgaBltBufferToVideo
,
1691 GlyphX
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1692 GlyphY
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1693 GLYPH_WIDTH
* Count
,
1695 GLYPH_WIDTH
* Count
* sizeof (EFI_UGA_PIXEL
)
1699 return ReturnStatus
;
1704 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
1707 GRAPHICS_CONSOLE_DEV
*Private
;
1708 EFI_SIMPLE_TEXT_OUTPUT_MODE
*CurrentMode
;
1711 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1712 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1713 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground
;
1714 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background
;
1715 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar
[GLYPH_HEIGHT
][GLYPH_WIDTH
];
1719 CurrentMode
= This
->Mode
;
1721 if (!CurrentMode
->CursorVisible
) {
1725 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1726 GraphicsOutput
= Private
->GraphicsOutput
;
1727 UgaDraw
= Private
->UgaDraw
;
1730 // BUGBUG - we need to think about what to do with wide and narrow character deletions.
1733 // Blt a character to the screen
1735 GlyphX
= (CurrentMode
->CursorColumn
* GLYPH_WIDTH
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaX
;
1736 GlyphY
= (CurrentMode
->CursorRow
* GLYPH_HEIGHT
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaY
;
1737 if (GraphicsOutput
!= NULL
) {
1738 GraphicsOutput
->Blt (
1740 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltChar
,
1741 EfiBltVideoToBltBuffer
,
1748 GLYPH_WIDTH
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1753 (EFI_UGA_PIXEL
*) (UINTN
) BltChar
,
1754 EfiUgaVideoToBltBuffer
,
1761 GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)
1765 GetTextColors (This
, &Foreground
.Pixel
, &Background
.Pixel
);
1768 // Convert Monochrome bitmap of the Glyph to BltBuffer structure
1770 for (Y
= 0; Y
< GLYPH_HEIGHT
; Y
++) {
1771 for (X
= 0; X
< GLYPH_WIDTH
; X
++) {
1772 if ((mCursorGlyph
.GlyphCol1
[Y
] & (1 << X
)) != 0) {
1773 BltChar
[Y
][GLYPH_WIDTH
- X
- 1].Raw
^= Foreground
.Raw
;
1778 if (GraphicsOutput
!= NULL
) {
1779 GraphicsOutput
->Blt (
1781 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltChar
,
1782 EfiBltBufferToVideo
,
1789 GLYPH_WIDTH
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1794 (EFI_UGA_PIXEL
*) (UINTN
) BltChar
,
1795 EfiUgaBltBufferToVideo
,
1802 GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)