2 This is the main routine for initializing the Graphics Console support routines.
4 Add all standard Glyphs from EFI 1.02 Specification
5 Implement optimal automatic Mode creation algorithm
6 Solve palette issues for mixed graphics and text
7 When does this protocol reset the palette?
9 Copyright (c) 2006 Intel Corporation. <BR>
10 All rights reserved. This program and the accompanying materials
11 are licensed and made available under the terms and conditions of the BSD License
12 which accompanies this distribution. The full text of the license may be found at
13 http://opensource.org/licenses/bsd-license.php
15 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
16 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 #include "GraphicsConsole.h"
23 // Function Prototypes
27 GraphicsConsoleControllerDriverSupported (
28 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
29 IN EFI_HANDLE Controller
,
30 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
35 GraphicsConsoleControllerDriverStart (
36 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
37 IN EFI_HANDLE Controller
,
38 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
43 GraphicsConsoleControllerDriverStop (
44 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
45 IN EFI_HANDLE Controller
,
46 IN UINTN NumberOfChildren
,
47 IN EFI_HANDLE
*ChildHandleBuffer
52 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
53 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Foreground
,
54 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Background
58 DrawUnicodeWeightAtCursor (
59 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
60 IN CHAR16 UnicodeWeight
64 DrawUnicodeWeightAtCursorN (
65 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
66 IN CHAR16
*UnicodeWeight
,
72 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
78 GRAPHICS_CONSOLE_DEV mGraphicsConsoleDevTemplate
= {
79 GRAPHICS_CONSOLE_DEV_SIGNATURE
,
80 (EFI_GRAPHICS_OUTPUT_PROTOCOL
*) NULL
,
81 (EFI_UGA_DRAW_PROTOCOL
*) NULL
,
83 GraphicsConsoleConOutReset
,
84 GraphicsConsoleConOutOutputString
,
85 GraphicsConsoleConOutTestString
,
86 GraphicsConsoleConOutQueryMode
,
87 GraphicsConsoleConOutSetMode
,
88 GraphicsConsoleConOutSetAttribute
,
89 GraphicsConsoleConOutClearScreen
,
90 GraphicsConsoleConOutSetCursorPosition
,
91 GraphicsConsoleConOutEnableCursor
,
92 (EFI_SIMPLE_TEXT_OUTPUT_MODE
*) NULL
97 EFI_TEXT_ATTR(EFI_LIGHTGRAY
, EFI_BLACK
),
103 { 80, 25, 0, 0, 0, 0 }, // Mode 0
104 { 80, 50, 0, 0, 0, 0 }, // Mode 1
105 { 0, 0, 0, 0, 0, 0 } // Mode 2
107 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) NULL
,
111 EFI_HII_PROTOCOL
*mHii
;
113 static CHAR16 mCrLfString
[3] = { CHAR_CARRIAGE_RETURN
, CHAR_LINEFEED
, CHAR_NULL
};
115 static EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors
[16] = {
119 {0x00, 0x00, 0x00, 0x00}, // BLACK
120 {0x98, 0x00, 0x00, 0x00}, // BLUE
121 {0x00, 0x98, 0x00, 0x00}, // GREEN
122 {0x98, 0x98, 0x00, 0x00}, // CYAN
123 {0x00, 0x00, 0x98, 0x00}, // RED
124 {0x98, 0x00, 0x98, 0x00}, // MAGENTA
125 {0x00, 0x98, 0x98, 0x00}, // BROWN
126 {0x98, 0x98, 0x98, 0x00}, // LIGHTGRAY
127 {0x30, 0x30, 0x30, 0x00}, // DARKGRAY - BRIGHT BLACK
128 {0xff, 0x00, 0x00, 0x00}, // LIGHTBLUE - ?
129 {0x00, 0xff, 0x00, 0x00}, // LIGHTGREEN - ?
130 {0xff, 0xff, 0x00, 0x00}, // LIGHTCYAN
131 {0x00, 0x00, 0xff, 0x00}, // LIGHTRED
132 {0xff, 0x00, 0xff, 0x00}, // LIGHTMAGENTA
133 {0x00, 0xff, 0xff, 0x00}, // LIGHTBROWN
134 {0xff, 0xff, 0xff, 0x00} // WHITE
137 static EFI_NARROW_GLYPH mCursorGlyph
= {
140 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF }
143 EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding
= {
144 GraphicsConsoleControllerDriverSupported
,
145 GraphicsConsoleControllerDriverStart
,
146 GraphicsConsoleControllerDriverStop
,
154 GraphicsConsoleControllerDriverSupported (
155 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
156 IN EFI_HANDLE Controller
,
157 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
161 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
162 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
163 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
167 // Open the IO Abstraction(s) needed to perform the supported test
169 Status
= gBS
->OpenProtocol (
171 &gEfiGraphicsOutputProtocolGuid
,
172 (VOID
**) &GraphicsOutput
,
173 This
->DriverBindingHandle
,
175 EFI_OPEN_PROTOCOL_BY_DRIVER
178 if (EFI_ERROR (Status
)) {
179 GraphicsOutput
= NULL
;
181 // Open Graphics Output Protocol failed, try to open UGA Draw Protocol
183 Status
= gBS
->OpenProtocol (
185 &gEfiUgaDrawProtocolGuid
,
187 This
->DriverBindingHandle
,
189 EFI_OPEN_PROTOCOL_BY_DRIVER
191 if (EFI_ERROR (Status
)) {
197 // We need to ensure that we do not layer on top of a virtual handle.
198 // We need to ensure that the handles produced by the conspliter do not
201 Status
= gBS
->OpenProtocol (
203 &gEfiDevicePathProtocolGuid
,
204 (VOID
**) &DevicePath
,
205 This
->DriverBindingHandle
,
207 EFI_OPEN_PROTOCOL_BY_DRIVER
209 if (!EFI_ERROR (Status
)) {
212 &gEfiDevicePathProtocolGuid
,
213 This
->DriverBindingHandle
,
220 // Does Hii Exist? If not, we aren't ready to run
222 Status
= EfiLocateHiiProtocol ();
225 // Close the I/O Abstraction(s) used to perform the supported test
228 if (GraphicsOutput
!= NULL
) {
231 &gEfiGraphicsOutputProtocolGuid
,
232 This
->DriverBindingHandle
,
238 &gEfiUgaDrawProtocolGuid
,
239 This
->DriverBindingHandle
,
248 GraphicsConsoleControllerDriverStart (
249 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
250 IN EFI_HANDLE Controller
,
251 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
257 Start the controller.
261 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
262 Controller - The handle of the controller to start.
263 RemainingDevicePath - A pointer to the remaining portion of a devcie path.
267 EFI_SUCCESS - Return successfully.
268 EFI_OUT_OF_RESOURCES - Out of resources.
273 GRAPHICS_CONSOLE_DEV
*Private
;
274 EFI_HII_PACKAGES
*Package
;
275 EFI_HII_FONT_PACK
*FontPack
;
276 UINTN NarrowFontSize
;
277 UINT32 HorizontalResolution
;
278 UINT32 VerticalResolution
;
287 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
292 // Initialize the Graphics Console device instance
294 Private
= AllocateCopyPool (
295 sizeof (GRAPHICS_CONSOLE_DEV
),
296 &mGraphicsConsoleDevTemplate
298 if (Private
== NULL
) {
299 return EFI_OUT_OF_RESOURCES
;
302 Private
->SimpleTextOutput
.Mode
= &(Private
->SimpleTextOutputMode
);
304 Status
= gBS
->OpenProtocol (
306 &gEfiGraphicsOutputProtocolGuid
,
307 (VOID
**) &Private
->GraphicsOutput
,
308 This
->DriverBindingHandle
,
310 EFI_OPEN_PROTOCOL_BY_DRIVER
312 if (EFI_ERROR(Status
)) {
313 Private
->GraphicsOutput
= NULL
;
315 Status
= gBS
->OpenProtocol (
317 &gEfiUgaDrawProtocolGuid
,
318 (VOID
**) &Private
->UgaDraw
,
319 This
->DriverBindingHandle
,
321 EFI_OPEN_PROTOCOL_BY_DRIVER
323 if (EFI_ERROR (Status
)) {
329 // Get the HII protocol. If Supported() succeeds, do we really
330 // need to get HII protocol again?
332 Status
= EfiLocateHiiProtocol ();
333 if (EFI_ERROR (Status
)) {
337 NarrowFontSize
= ReturnNarrowFontSize ();
339 FontPack
= AllocateZeroPool (sizeof (EFI_HII_FONT_PACK
) + NarrowFontSize
);
342 FontPack
->Header
.Length
= (UINT32
) (sizeof (EFI_HII_FONT_PACK
) + NarrowFontSize
);
343 FontPack
->Header
.Type
= EFI_HII_FONT
;
344 FontPack
->NumberOfNarrowGlyphs
= (UINT16
) (NarrowFontSize
/ sizeof (EFI_NARROW_GLYPH
));
346 Location
= (UINT8
*) (&FontPack
->NumberOfWideGlyphs
+ sizeof (UINT8
));
347 CopyMem (Location
, UsStdNarrowGlyphData
, NarrowFontSize
);
350 // Register our Fonts into the global database
352 Package
= PreparePackages (1, NULL
, FontPack
);
353 mHii
->NewPack (mHii
, Package
, &(Private
->HiiHandle
));
354 gBS
->FreePool (Package
);
357 // Free the font database
359 gBS
->FreePool (FontPack
);
362 // If the current mode information can not be retrieved, then attemp to set the default mode
363 // of 800x600, 32 bit colot, 60 Hz refresh.
365 HorizontalResolution
= 800;
366 VerticalResolution
= 600;
368 if (Private
->GraphicsOutput
!= NULL
) {
370 // The console is build on top of Graphics Output Protocol, find the mode number for 800x600
372 for (ModeNumber
= 0; ModeNumber
< Private
->GraphicsOutput
->Mode
->MaxMode
; ModeNumber
++) {
373 Status
= Private
->GraphicsOutput
->QueryMode (
374 Private
->GraphicsOutput
,
379 if (!EFI_ERROR (Status
)) {
380 if ((Info
->HorizontalResolution
== 800) &&
381 (Info
->VerticalResolution
== 600)) {
382 Status
= Private
->GraphicsOutput
->SetMode (Private
->GraphicsOutput
, ModeNumber
);
383 if (!EFI_ERROR (Status
)) {
384 gBS
->FreePool (Info
);
388 gBS
->FreePool (Info
);
392 if (EFI_ERROR (Status
) || (ModeNumber
== Private
->GraphicsOutput
->Mode
->MaxMode
)) {
394 // Set default mode failed or device don't support default mode, then get the current mode information
396 HorizontalResolution
= Private
->GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
397 VerticalResolution
= Private
->GraphicsOutput
->Mode
->Info
->VerticalResolution
;
398 ModeNumber
= Private
->GraphicsOutput
->Mode
->Mode
;
402 // The console is build on top of UGA Draw Protocol
406 Status
= Private
->UgaDraw
->SetMode (
408 HorizontalResolution
,
413 if (EFI_ERROR (Status
)) {
415 // Get the current mode information from the UGA Draw Protocol
417 Status
= Private
->UgaDraw
->GetMode (
419 &HorizontalResolution
,
424 if (EFI_ERROR (Status
)) {
431 // Compute the maximum number of text Rows and Columns that this current graphics mode can support
433 Columns
= HorizontalResolution
/ GLYPH_WIDTH
;
434 Rows
= VerticalResolution
/ GLYPH_HEIGHT
;
437 // See if the mode is too small to support the required 80x25 text mode
439 if (Columns
< 80 || Rows
< 25) {
443 // Add Mode #0 that must be 80x25
446 Private
->ModeData
[MaxMode
].GopWidth
= HorizontalResolution
;
447 Private
->ModeData
[MaxMode
].GopHeight
= VerticalResolution
;
448 Private
->ModeData
[MaxMode
].GopModeNumber
= ModeNumber
;
449 Private
->ModeData
[MaxMode
].DeltaX
= (HorizontalResolution
- (80 * GLYPH_WIDTH
)) >> 1;
450 Private
->ModeData
[MaxMode
].DeltaY
= (VerticalResolution
- (25 * GLYPH_HEIGHT
)) >> 1;
454 // If it is possible to support Mode #1 - 80x50, than add it as an active mode
457 Private
->ModeData
[MaxMode
].GopWidth
= HorizontalResolution
;
458 Private
->ModeData
[MaxMode
].GopHeight
= VerticalResolution
;
459 Private
->ModeData
[MaxMode
].GopModeNumber
= ModeNumber
;
460 Private
->ModeData
[MaxMode
].DeltaX
= (HorizontalResolution
- (80 * GLYPH_WIDTH
)) >> 1;
461 Private
->ModeData
[MaxMode
].DeltaY
= (VerticalResolution
- (50 * GLYPH_HEIGHT
)) >> 1;
465 // If the graphics mode is 800x600, than add a text mode that uses the entire display
467 if (HorizontalResolution
== 800 && VerticalResolution
== 600) {
470 Private
->ModeData
[MaxMode
].Columns
= 0;
471 Private
->ModeData
[MaxMode
].Rows
= 0;
472 Private
->ModeData
[MaxMode
].GopWidth
= 800;
473 Private
->ModeData
[MaxMode
].GopHeight
= 600;
474 Private
->ModeData
[MaxMode
].GopModeNumber
= ModeNumber
;
475 Private
->ModeData
[MaxMode
].DeltaX
= 0;
476 Private
->ModeData
[MaxMode
].DeltaY
= 0;
480 Private
->ModeData
[MaxMode
].Columns
= 800 / GLYPH_WIDTH
;
481 Private
->ModeData
[MaxMode
].Rows
= 600 / GLYPH_HEIGHT
;
482 Private
->ModeData
[MaxMode
].GopWidth
= 800;
483 Private
->ModeData
[MaxMode
].GopHeight
= 600;
484 Private
->ModeData
[MaxMode
].GopModeNumber
= ModeNumber
;
485 Private
->ModeData
[MaxMode
].DeltaX
= (800 % GLYPH_WIDTH
) >> 1;
486 Private
->ModeData
[MaxMode
].DeltaY
= (600 % GLYPH_HEIGHT
) >> 1;
490 // Update the maximum number of modes
492 Private
->SimpleTextOutputMode
.MaxMode
= (INT32
) MaxMode
;
495 // Determine the number of text modes that this protocol can support
497 Status
= GraphicsConsoleConOutSetMode (&Private
->SimpleTextOutput
, 0);
498 if (EFI_ERROR (Status
)) {
503 GraphicsConsoleConOutOutputString (&Private
->SimpleTextOutput
, (CHAR16
*)L
"Graphics Console Started\n\r");
507 // Install protocol interfaces for the Graphics Console device.
509 Status
= gBS
->InstallMultipleProtocolInterfaces (
511 &gEfiSimpleTextOutProtocolGuid
,
512 &Private
->SimpleTextOutput
,
517 if (EFI_ERROR (Status
)) {
519 // Close the GOP or UGA IO Protocol
521 if (Private
->GraphicsOutput
!= NULL
) {
524 &gEfiGraphicsOutputProtocolGuid
,
525 This
->DriverBindingHandle
,
531 &gEfiUgaDrawProtocolGuid
,
532 This
->DriverBindingHandle
,
540 if (Private
!= NULL
) {
541 gBS
->FreePool (Private
->LineBuffer
);
542 gBS
->FreePool (Private
);
551 GraphicsConsoleControllerDriverStop (
552 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
553 IN EFI_HANDLE Controller
,
554 IN UINTN NumberOfChildren
,
555 IN EFI_HANDLE
*ChildHandleBuffer
559 EFI_SIMPLE_TEXT_OUT_PROTOCOL
*SimpleTextOutput
;
560 GRAPHICS_CONSOLE_DEV
*Private
;
562 Status
= gBS
->OpenProtocol (
564 &gEfiSimpleTextOutProtocolGuid
,
565 (VOID
**) &SimpleTextOutput
,
566 This
->DriverBindingHandle
,
568 EFI_OPEN_PROTOCOL_GET_PROTOCOL
570 if (EFI_ERROR (Status
)) {
571 return EFI_NOT_STARTED
;
574 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
576 Status
= gBS
->UninstallProtocolInterface (
578 &gEfiSimpleTextOutProtocolGuid
,
579 &Private
->SimpleTextOutput
582 if (!EFI_ERROR (Status
)) {
584 // Close the GOP or UGA IO Protocol
586 if (Private
->GraphicsOutput
!= NULL
) {
589 &gEfiGraphicsOutputProtocolGuid
,
590 This
->DriverBindingHandle
,
596 &gEfiUgaDrawProtocolGuid
,
597 This
->DriverBindingHandle
,
603 // Remove the font pack
605 mHii
->RemovePack (mHii
, Private
->HiiHandle
);
608 // Free our instance data
610 if (Private
!= NULL
) {
611 gBS
->FreePool (Private
->LineBuffer
);
612 gBS
->FreePool (Private
);
620 EfiLocateHiiProtocol (
626 Find if the HII protocol is available. If yes, locate the HII protocol
639 // There should only be one - so buffer size is this
641 Size
= sizeof (EFI_HANDLE
);
643 Status
= gBS
->LocateHandle (
645 &gEfiHiiProtocolGuid
,
651 if (EFI_ERROR (Status
)) {
655 Status
= gBS
->HandleProtocol (
657 &gEfiHiiProtocolGuid
,
664 // Body of the STO functions
668 GraphicsConsoleConOutReset (
669 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
670 IN BOOLEAN ExtendedVerification
675 Implements SIMPLE_TEXT_OUTPUT.Reset().
676 If ExtendeVerification is TRUE, then perform dependent Graphics Console
677 device reset, and set display mode to mode 0.
678 If ExtendedVerification is FALSE, only set display mode to mode 0.
682 This - Indicates the calling context.
684 ExtendedVerification - Indicates that the driver may perform a more exhaustive
685 verification operation of the device during reset.
690 The reset operation succeeds.
693 The Graphics Console is not functioning correctly
697 This
->SetAttribute (This
, EFI_TEXT_ATTR (This
->Mode
->Attribute
& 0x0F, EFI_BACKGROUND_BLACK
));
698 return This
->SetMode (This
, 0);
703 GraphicsConsoleConOutOutputString (
704 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
710 Implements SIMPLE_TEXT_OUTPUT.OutputString().
711 The Unicode string will be converted to Glyphs and will be
712 sent to the Graphics Console.
717 This - Indicates the calling context.
719 WString - The Null-terminated Unicode string to be displayed on
720 the Graphics Console.
725 The string is output successfully.
728 The Graphics Console failed to send the string out.
730 EFI_WARN_UNKNOWN_GLYPH
731 Indicates that some of the characters in the Unicode string could not
732 be rendered and are skipped.
736 GRAPHICS_CONSOLE_DEV
*Private
;
737 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
738 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
747 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
748 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
753 INT32 OriginAttribute
;
754 CHAR16 SpaceStr
[] = { NARROW_CHAR
, ' ', 0 };
759 Mode
= This
->Mode
->Mode
;
760 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
761 GraphicsOutput
= Private
->GraphicsOutput
;
762 UgaDraw
= Private
->UgaDraw
;
764 MaxColumn
= Private
->ModeData
[Mode
].Columns
;
765 MaxRow
= Private
->ModeData
[Mode
].Rows
;
766 DeltaX
= Private
->ModeData
[Mode
].DeltaX
;
767 DeltaY
= Private
->ModeData
[Mode
].DeltaY
;
768 Width
= MaxColumn
* GLYPH_WIDTH
;
769 Height
= (MaxRow
- 1) * GLYPH_HEIGHT
;
770 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
773 // The Attributes won't change when during the time OutputString is called
775 GetTextColors (This
, &Foreground
, &Background
);
784 OriginAttribute
= This
->Mode
->Attribute
;
788 if (*WString
== CHAR_BACKSPACE
) {
790 // If the cursor is at the left edge of the display, then move the cursor
793 if (This
->Mode
->CursorColumn
== 0 && This
->Mode
->CursorRow
> 0) {
794 This
->Mode
->CursorRow
--;
795 This
->Mode
->CursorColumn
= (INT32
) (MaxColumn
- 1);
796 This
->OutputString (This
, SpaceStr
);
798 This
->Mode
->CursorRow
--;
799 This
->Mode
->CursorColumn
= (INT32
) (MaxColumn
- 1);
800 } else if (This
->Mode
->CursorColumn
> 0) {
802 // If the cursor is not at the left edge of the display, then move the cursor
805 This
->Mode
->CursorColumn
--;
806 This
->OutputString (This
, SpaceStr
);
808 This
->Mode
->CursorColumn
--;
813 } else if (*WString
== CHAR_LINEFEED
) {
815 // If the cursor is at the bottom of the display, then scroll the display one
816 // row, and do not update the cursor position. Otherwise, move the cursor
819 if (This
->Mode
->CursorRow
== (INT32
) (MaxRow
- 1)) {
820 if (GraphicsOutput
!= NULL
) {
822 // Scroll Screen Up One Row
824 GraphicsOutput
->Blt (
829 DeltaY
+ GLYPH_HEIGHT
,
838 // Print Blank Line at last line
840 GraphicsOutput
->Blt (
854 // Scroll Screen Up One Row
861 DeltaY
+ GLYPH_HEIGHT
,
870 // Print Blank Line at last line
874 (EFI_UGA_PIXEL
*) (UINTN
) &Background
,
886 This
->Mode
->CursorRow
++;
891 } else if (*WString
== CHAR_CARRIAGE_RETURN
) {
893 // Move the cursor to the beginning of the current row.
895 This
->Mode
->CursorColumn
= 0;
898 } else if (*WString
== WIDE_CHAR
) {
900 This
->Mode
->Attribute
|= EFI_WIDE_ATTRIBUTE
;
903 } else if (*WString
== NARROW_CHAR
) {
905 This
->Mode
->Attribute
&= (~ (UINT32
) EFI_WIDE_ATTRIBUTE
);
910 // Print the character at the current cursor position and move the cursor
911 // right one column. If this moves the cursor past the right edge of the
912 // display, then the line should wrap to the beginning of the next line. This
913 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the
914 // bottom of the display, and the line wraps, then the display will be scrolled
916 // If wide char is going to be displayed, need to display one character at a time
917 // Or, need to know the display length of a certain string.
919 // Index is used to determine how many character width units (wide = 2, narrow = 1)
920 // Count is used to determine how many characters are used regardless of their attributes
922 for (Count
= 0, Index
= 0; (This
->Mode
->CursorColumn
+ Index
) < MaxColumn
; Count
++, Index
++) {
923 if (WString
[Count
] == CHAR_NULL
) {
927 if (WString
[Count
] == CHAR_BACKSPACE
) {
931 if (WString
[Count
] == CHAR_LINEFEED
) {
935 if (WString
[Count
] == CHAR_CARRIAGE_RETURN
) {
939 if (WString
[Count
] == WIDE_CHAR
) {
943 if (WString
[Count
] == NARROW_CHAR
) {
947 // Is the wide attribute on?
949 if (This
->Mode
->Attribute
& EFI_WIDE_ATTRIBUTE
) {
951 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop
955 // This is the end-case where if we are at column 79 and about to print a wide character
956 // We should prevent this from happening because we will wrap inappropriately. We should
957 // not print this character until the next line.
959 if ((This
->Mode
->CursorColumn
+ Index
+ 1) > MaxColumn
) {
966 Status
= DrawUnicodeWeightAtCursorN (This
, WString
, Count
);
967 if (EFI_ERROR (Status
)) {
971 // At the end of line, output carriage return and line feed
974 This
->Mode
->CursorColumn
+= (INT32
) Index
;
975 if (This
->Mode
->CursorColumn
> (INT32
) MaxColumn
) {
976 This
->Mode
->CursorColumn
-= 2;
977 This
->OutputString (This
, SpaceStr
);
980 if (This
->Mode
->CursorColumn
>= (INT32
) MaxColumn
) {
982 This
->OutputString (This
, mCrLfString
);
988 This
->Mode
->Attribute
= OriginAttribute
;
993 return EFI_WARN_UNKNOWN_GLYPH
;
1001 GraphicsConsoleConOutTestString (
1002 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1006 Routine Description:
1008 Implements SIMPLE_TEXT_OUTPUT.TestString().
1009 If one of the characters in the *Wstring is
1010 neither valid valid Unicode drawing characters,
1011 not ASCII code, then this function will return
1017 This - Indicates the calling context.
1019 WString - The Null-terminated Unicode string to be tested.
1024 The Graphics Console is capable of rendering the output string.
1027 Some of the characters in the Unicode string cannot be rendered.
1040 while (WString
[Count
]) {
1041 Status
= mHii
->GetGlyph (
1050 if (EFI_ERROR (Status
)) {
1051 return EFI_UNSUPPORTED
;
1060 GraphicsConsoleConOutQueryMode (
1061 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1062 IN UINTN ModeNumber
,
1067 Routine Description:
1069 Implements SIMPLE_TEXT_OUTPUT.QueryMode().
1070 It returnes information for an available text mode
1071 that the Graphics Console supports.
1072 In this driver,we only support text mode 80x25, which is
1078 This - Indicates the calling context.
1080 ModeNumber - The mode number to return information on.
1082 Columns - The returned columns of the requested mode.
1084 Rows - The returned rows of the requested mode.
1089 The requested mode information is returned.
1092 The mode number is not valid.
1096 GRAPHICS_CONSOLE_DEV
*Private
;
1098 if (ModeNumber
>= (UINTN
) This
->Mode
->MaxMode
) {
1099 return EFI_UNSUPPORTED
;
1102 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1104 *Columns
= Private
->ModeData
[ModeNumber
].Columns
;
1105 *Rows
= Private
->ModeData
[ModeNumber
].Rows
;
1107 if (*Columns
<= 0 && *Rows
<= 0) {
1108 return EFI_UNSUPPORTED
;
1117 GraphicsConsoleConOutSetMode (
1118 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1122 Routine Description:
1124 Implements SIMPLE_TEXT_OUTPUT.SetMode().
1125 Set the Graphics Console to a specified mode.
1126 In this driver, we only support mode 0.
1130 This - Indicates the calling context.
1132 ModeNumber - The text mode to set.
1137 The requested text mode is set.
1140 The requested text mode cannot be set because of Graphics Console device error.
1143 The text mode number is not valid.
1148 GRAPHICS_CONSOLE_DEV
*Private
;
1149 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1150 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*NewLineBuffer
;
1151 UINT32 HorizontalResolution
;
1152 UINT32 VerticalResolution
;
1153 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1154 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1158 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1159 GraphicsOutput
= Private
->GraphicsOutput
;
1160 UgaDraw
= Private
->UgaDraw
;
1161 ModeData
= &(Private
->ModeData
[ModeNumber
]);
1163 if (ModeData
->Columns
<= 0 && ModeData
->Rows
<= 0) {
1164 return EFI_UNSUPPORTED
;
1168 // Make sure the requested mode number is supported
1170 if (ModeNumber
>= (UINTN
) This
->Mode
->MaxMode
) {
1171 return EFI_UNSUPPORTED
;
1174 if (ModeData
->Columns
<= 0 && ModeData
->Rows
<= 0) {
1175 return EFI_UNSUPPORTED
;
1178 // Attempt to allocate a line buffer for the requested mode number
1180 Status
= gBS
->AllocatePool (
1181 EfiBootServicesData
,
1182 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * ModeData
->Columns
* GLYPH_WIDTH
* GLYPH_HEIGHT
,
1183 (VOID
**) &NewLineBuffer
1185 if (EFI_ERROR (Status
)) {
1187 // The new line buffer could not be allocated, so return an error.
1188 // No changes to the state of the current console have been made, so the current console is still valid
1193 // If the mode has been set at least one other time, then LineBuffer will not be NULL
1195 if (Private
->LineBuffer
!= NULL
) {
1197 // Clear the current text window on the current graphics console
1199 This
->ClearScreen (This
);
1202 // If the new mode is the same as the old mode, then just return EFI_SUCCESS
1204 if ((INT32
) ModeNumber
== This
->Mode
->Mode
) {
1205 gBS
->FreePool (NewLineBuffer
);
1209 // Otherwise, the size of the text console and/or the UGA mode will be changed,
1210 // so turn off the cursor, and free the LineBuffer for the current mode
1212 This
->EnableCursor (This
, FALSE
);
1214 gBS
->FreePool (Private
->LineBuffer
);
1217 // Assign the current line buffer to the newly allocated line buffer
1219 Private
->LineBuffer
= NewLineBuffer
;
1221 if (GraphicsOutput
!= NULL
) {
1222 if (ModeData
->GopModeNumber
!= GraphicsOutput
->Mode
->Mode
) {
1224 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new grapghics mode
1226 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeData
->GopModeNumber
);
1227 if (EFI_ERROR (Status
)) {
1229 // The mode set operation failed
1235 // The current graphics mode is correct, so simply clear the entire display
1237 Status
= GraphicsOutput
->Blt (
1246 ModeData
->GopHeight
,
1252 // Get the current UGA Draw mode information
1254 Status
= UgaDraw
->GetMode (
1256 &HorizontalResolution
,
1257 &VerticalResolution
,
1261 if (EFI_ERROR (Status
) || HorizontalResolution
!= ModeData
->GopWidth
|| VerticalResolution
!= ModeData
->GopHeight
) {
1263 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new grapghics mode
1265 Status
= UgaDraw
->SetMode (
1268 ModeData
->GopHeight
,
1272 if (EFI_ERROR (Status
)) {
1274 // The mode set operation failed
1280 // The current graphics mode is correct, so simply clear the entire display
1282 Status
= UgaDraw
->Blt (
1284 (EFI_UGA_PIXEL
*) (UINTN
) &mEfiColors
[0],
1291 ModeData
->GopHeight
,
1298 // The new mode is valid, so commit the mode change
1300 This
->Mode
->Mode
= (INT32
) ModeNumber
;
1303 // Move the text cursor to the upper left hand corner of the displat and enable it
1305 This
->SetCursorPosition (This
, 0, 0);
1306 This
->EnableCursor (This
, TRUE
);
1313 GraphicsConsoleConOutSetAttribute (
1314 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1318 Routine Description:
1320 Implements SIMPLE_TEXT_OUTPUT.SetAttribute().
1324 This - Indicates the calling context.
1326 Attrubute - The attribute to set. Only bit0..6 are valid, all other bits
1327 are undefined and must be zero.
1332 The requested attribute is set.
1335 The requested attribute cannot be set due to Graphics Console port error.
1338 The attribute requested is not defined by EFI spec.
1342 if ((Attribute
| 0xFF) != 0xFF) {
1343 return EFI_UNSUPPORTED
;
1346 if ((INT32
) Attribute
== This
->Mode
->Attribute
) {
1352 This
->Mode
->Attribute
= (INT32
) Attribute
;
1361 GraphicsConsoleConOutClearScreen (
1362 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
1365 Routine Description:
1367 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().
1368 It clears the Graphics Console's display to the
1369 currently selected background color.
1374 This - Indicates the calling context.
1379 The operation completed successfully.
1382 The Graphics Console cannot be cleared due to Graphics Console device error.
1385 The Graphics Console is not in a valid text mode.
1390 GRAPHICS_CONSOLE_DEV
*Private
;
1391 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1392 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1393 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1394 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
1395 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
1397 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1398 GraphicsOutput
= Private
->GraphicsOutput
;
1399 UgaDraw
= Private
->UgaDraw
;
1400 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1402 GetTextColors (This
, &Foreground
, &Background
);
1403 if (GraphicsOutput
!= NULL
) {
1404 Status
= GraphicsOutput
->Blt (
1413 ModeData
->GopHeight
,
1417 Status
= UgaDraw
->Blt (
1419 (EFI_UGA_PIXEL
*) (UINTN
) &Background
,
1426 ModeData
->GopHeight
,
1431 This
->Mode
->CursorColumn
= 0;
1432 This
->Mode
->CursorRow
= 0;
1441 GraphicsConsoleConOutSetCursorPosition (
1442 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1447 Routine Description:
1449 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().
1453 This - Indicates the calling context.
1455 Column - The row to set cursor to.
1457 Row - The column to set cursor to.
1462 The operation completed successfully.
1465 The request fails due to Graphics Console device error.
1468 The Graphics Console is not in a valid text mode, or the cursor position
1469 is invalid for current mode.
1473 GRAPHICS_CONSOLE_DEV
*Private
;
1474 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1476 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1477 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1479 if ((Column
>= ModeData
->Columns
) || (Row
>= ModeData
->Rows
)) {
1480 return EFI_UNSUPPORTED
;
1483 if (((INT32
) Column
== This
->Mode
->CursorColumn
) && ((INT32
) Row
== This
->Mode
->CursorRow
)) {
1489 This
->Mode
->CursorColumn
= (INT32
) Column
;
1490 This
->Mode
->CursorRow
= (INT32
) Row
;
1499 GraphicsConsoleConOutEnableCursor (
1500 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1504 Routine Description:
1506 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
1507 In this driver, the cursor cannot be hidden.
1511 This - Indicates the calling context.
1513 Visible - If TRUE, the cursor is set to be visible,
1514 If FALSE, the cursor is set to be invisible.
1519 The request is valid.
1522 The Graphics Console does not support a hidden cursor.
1528 This
->Mode
->CursorVisible
= Visible
;
1537 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1538 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Foreground
,
1539 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Background
1544 Attribute
= This
->Mode
->Attribute
& 0x7F;
1546 *Foreground
= mEfiColors
[Attribute
& 0x0f];
1547 *Background
= mEfiColors
[Attribute
>> 4];
1553 DrawUnicodeWeightAtCursorN (
1554 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1555 IN CHAR16
*UnicodeWeight
,
1559 GRAPHICS_CONSOLE_DEV
*Private
;
1561 EFI_STATUS ReturnStatus
;
1563 GLYPH_UNION GlyphData
;
1566 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1567 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1568 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
1569 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
1576 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1578 ReturnStatus
= EFI_SUCCESS
;
1582 GetTextColors (This
, &Foreground
, &Background
);
1586 while (Index
< Count
) {
1587 if (This
->Mode
->Attribute
& EFI_WIDE_ATTRIBUTE
) {
1588 GlyphStatus
= WIDE_CHAR
;
1590 GlyphStatus
= NARROW_CHAR
;
1593 Status
= mHii
->GetGlyph (
1601 if (EFI_ERROR (Status
)) {
1602 ReturnStatus
= Status
;
1607 CopyMem (&GlyphData
, Glyph
, sizeof (GLYPH_UNION
));
1611 // We are creating the second half of the wide character's BLT buffer
1613 if (GlyphWidth
== 0x10 && Counts
== 1) {
1614 CopyMem (&GlyphData
.NarrowGlyph
.GlyphCol1
, &Glyph
->WideGlyph
.GlyphCol2
, sizeof (Glyph
->WideGlyph
.GlyphCol2
));
1619 if (GlyphWidth
== 0x10) {
1622 (UINT8
*) &GlyphData
,
1628 &Private
->LineBuffer
[ArrayIndex
* GLYPH_WIDTH
]
1633 (UINT8
*) &GlyphData
,
1639 &Private
->LineBuffer
[ArrayIndex
* GLYPH_WIDTH
]
1645 } while (Counts
< 2 && GlyphWidth
== 0x10);
1649 // If we are printing Wide characters, treat the BLT as if it is twice as many characters
1651 if (GlyphWidth
== 0x10) {
1655 // Blt a character to the screen
1657 GlyphX
= This
->Mode
->CursorColumn
* GLYPH_WIDTH
;
1658 GlyphY
= This
->Mode
->CursorRow
* GLYPH_HEIGHT
;
1659 GraphicsOutput
= Private
->GraphicsOutput
;
1660 UgaDraw
= Private
->UgaDraw
;
1661 if (GraphicsOutput
!= NULL
) {
1662 GraphicsOutput
->Blt (
1664 Private
->LineBuffer
,
1665 EfiBltBufferToVideo
,
1668 GlyphX
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1669 GlyphY
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1670 GLYPH_WIDTH
* Count
,
1672 GLYPH_WIDTH
* Count
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1677 (EFI_UGA_PIXEL
*) (UINTN
) Private
->LineBuffer
,
1678 EfiUgaBltBufferToVideo
,
1681 GlyphX
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1682 GlyphY
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1683 GLYPH_WIDTH
* Count
,
1685 GLYPH_WIDTH
* Count
* sizeof (EFI_UGA_PIXEL
)
1689 return ReturnStatus
;
1694 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
1697 GRAPHICS_CONSOLE_DEV
*Private
;
1698 EFI_SIMPLE_TEXT_OUTPUT_MODE
*CurrentMode
;
1701 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1702 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1703 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground
;
1704 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background
;
1705 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar
[GLYPH_HEIGHT
][GLYPH_WIDTH
];
1709 CurrentMode
= This
->Mode
;
1711 if (!CurrentMode
->CursorVisible
) {
1715 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1716 GraphicsOutput
= Private
->GraphicsOutput
;
1717 UgaDraw
= Private
->UgaDraw
;
1720 // BUGBUG - we need to think about what to do with wide and narrow character deletions.
1723 // Blt a character to the screen
1725 GlyphX
= (CurrentMode
->CursorColumn
* GLYPH_WIDTH
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaX
;
1726 GlyphY
= (CurrentMode
->CursorRow
* GLYPH_HEIGHT
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaY
;
1727 if (GraphicsOutput
!= NULL
) {
1728 GraphicsOutput
->Blt (
1730 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltChar
,
1731 EfiBltVideoToBltBuffer
,
1738 GLYPH_WIDTH
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1743 (EFI_UGA_PIXEL
*) (UINTN
) BltChar
,
1744 EfiUgaVideoToBltBuffer
,
1751 GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)
1755 GetTextColors (This
, &Foreground
.Pixel
, &Background
.Pixel
);
1758 // Convert Monochrome bitmap of the Glyph to BltBuffer structure
1760 for (Y
= 0; Y
< GLYPH_HEIGHT
; Y
++) {
1761 for (X
= 0; X
< GLYPH_WIDTH
; X
++) {
1762 if ((mCursorGlyph
.GlyphCol1
[Y
] & (1 << X
)) != 0) {
1763 BltChar
[Y
][GLYPH_WIDTH
- X
- 1].Raw
^= Foreground
.Raw
;
1768 if (GraphicsOutput
!= NULL
) {
1769 GraphicsOutput
->Blt (
1771 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltChar
,
1772 EfiBltBufferToVideo
,
1779 GLYPH_WIDTH
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1784 (EFI_UGA_PIXEL
*) (UINTN
) BltChar
,
1785 EfiUgaBltBufferToVideo
,
1792 GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)