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.
1035 GRAPHICS_CONSOLE_DEV
*Private
;
1038 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1042 while (WString
[Count
]) {
1043 Status
= mHii
->GetGlyph (
1052 if (EFI_ERROR (Status
)) {
1053 return EFI_UNSUPPORTED
;
1062 GraphicsConsoleConOutQueryMode (
1063 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1064 IN UINTN ModeNumber
,
1069 Routine Description:
1071 Implements SIMPLE_TEXT_OUTPUT.QueryMode().
1072 It returnes information for an available text mode
1073 that the Graphics Console supports.
1074 In this driver,we only support text mode 80x25, which is
1080 This - Indicates the calling context.
1082 ModeNumber - The mode number to return information on.
1084 Columns - The returned columns of the requested mode.
1086 Rows - The returned rows of the requested mode.
1091 The requested mode information is returned.
1094 The mode number is not valid.
1098 GRAPHICS_CONSOLE_DEV
*Private
;
1100 if (ModeNumber
>= (UINTN
) This
->Mode
->MaxMode
) {
1101 return EFI_UNSUPPORTED
;
1104 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1106 *Columns
= Private
->ModeData
[ModeNumber
].Columns
;
1107 *Rows
= Private
->ModeData
[ModeNumber
].Rows
;
1109 if (*Columns
<= 0 && *Rows
<= 0) {
1110 return EFI_UNSUPPORTED
;
1119 GraphicsConsoleConOutSetMode (
1120 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1124 Routine Description:
1126 Implements SIMPLE_TEXT_OUTPUT.SetMode().
1127 Set the Graphics Console to a specified mode.
1128 In this driver, we only support mode 0.
1132 This - Indicates the calling context.
1134 ModeNumber - The text mode to set.
1139 The requested text mode is set.
1142 The requested text mode cannot be set because of Graphics Console device error.
1145 The text mode number is not valid.
1150 GRAPHICS_CONSOLE_DEV
*Private
;
1151 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1152 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*NewLineBuffer
;
1153 UINT32 HorizontalResolution
;
1154 UINT32 VerticalResolution
;
1155 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1156 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1160 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1161 GraphicsOutput
= Private
->GraphicsOutput
;
1162 UgaDraw
= Private
->UgaDraw
;
1163 ModeData
= &(Private
->ModeData
[ModeNumber
]);
1165 if (ModeData
->Columns
<= 0 && ModeData
->Rows
<= 0) {
1166 return EFI_UNSUPPORTED
;
1170 // Make sure the requested mode number is supported
1172 if (ModeNumber
>= (UINTN
) This
->Mode
->MaxMode
) {
1173 return EFI_UNSUPPORTED
;
1176 if (ModeData
->Columns
<= 0 && ModeData
->Rows
<= 0) {
1177 return EFI_UNSUPPORTED
;
1180 // Attempt to allocate a line buffer for the requested mode number
1182 Status
= gBS
->AllocatePool (
1183 EfiBootServicesData
,
1184 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * ModeData
->Columns
* GLYPH_WIDTH
* GLYPH_HEIGHT
,
1185 (VOID
**) &NewLineBuffer
1187 if (EFI_ERROR (Status
)) {
1189 // The new line buffer could not be allocated, so return an error.
1190 // No changes to the state of the current console have been made, so the current console is still valid
1195 // If the mode has been set at least one other time, then LineBuffer will not be NULL
1197 if (Private
->LineBuffer
!= NULL
) {
1199 // Clear the current text window on the current graphics console
1201 This
->ClearScreen (This
);
1204 // If the new mode is the same as the old mode, then just return EFI_SUCCESS
1206 if ((INT32
) ModeNumber
== This
->Mode
->Mode
) {
1207 gBS
->FreePool (NewLineBuffer
);
1211 // Otherwise, the size of the text console and/or the UGA mode will be changed,
1212 // so turn off the cursor, and free the LineBuffer for the current mode
1214 This
->EnableCursor (This
, FALSE
);
1216 gBS
->FreePool (Private
->LineBuffer
);
1219 // Assign the current line buffer to the newly allocated line buffer
1221 Private
->LineBuffer
= NewLineBuffer
;
1223 if (GraphicsOutput
!= NULL
) {
1224 if (ModeData
->GopModeNumber
!= GraphicsOutput
->Mode
->Mode
) {
1226 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new grapghics mode
1228 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeData
->GopModeNumber
);
1229 if (EFI_ERROR (Status
)) {
1231 // The mode set operation failed
1237 // The current graphics mode is correct, so simply clear the entire display
1239 Status
= GraphicsOutput
->Blt (
1248 ModeData
->GopHeight
,
1254 // Get the current UGA Draw mode information
1256 Status
= UgaDraw
->GetMode (
1258 &HorizontalResolution
,
1259 &VerticalResolution
,
1263 if (EFI_ERROR (Status
) || HorizontalResolution
!= ModeData
->GopWidth
|| VerticalResolution
!= ModeData
->GopHeight
) {
1265 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new grapghics mode
1267 Status
= UgaDraw
->SetMode (
1270 ModeData
->GopHeight
,
1274 if (EFI_ERROR (Status
)) {
1276 // The mode set operation failed
1282 // The current graphics mode is correct, so simply clear the entire display
1284 Status
= UgaDraw
->Blt (
1286 (EFI_UGA_PIXEL
*) (UINTN
) &mEfiColors
[0],
1293 ModeData
->GopHeight
,
1300 // The new mode is valid, so commit the mode change
1302 This
->Mode
->Mode
= (INT32
) ModeNumber
;
1305 // Move the text cursor to the upper left hand corner of the displat and enable it
1307 This
->SetCursorPosition (This
, 0, 0);
1308 This
->EnableCursor (This
, TRUE
);
1315 GraphicsConsoleConOutSetAttribute (
1316 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1320 Routine Description:
1322 Implements SIMPLE_TEXT_OUTPUT.SetAttribute().
1326 This - Indicates the calling context.
1328 Attrubute - The attribute to set. Only bit0..6 are valid, all other bits
1329 are undefined and must be zero.
1334 The requested attribute is set.
1337 The requested attribute cannot be set due to Graphics Console port error.
1340 The attribute requested is not defined by EFI spec.
1344 if ((Attribute
| 0xFF) != 0xFF) {
1345 return EFI_UNSUPPORTED
;
1348 if ((INT32
) Attribute
== This
->Mode
->Attribute
) {
1354 This
->Mode
->Attribute
= (INT32
) Attribute
;
1363 GraphicsConsoleConOutClearScreen (
1364 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
1367 Routine Description:
1369 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().
1370 It clears the Graphics Console's display to the
1371 currently selected background color.
1376 This - Indicates the calling context.
1381 The operation completed successfully.
1384 The Graphics Console cannot be cleared due to Graphics Console device error.
1387 The Graphics Console is not in a valid text mode.
1392 GRAPHICS_CONSOLE_DEV
*Private
;
1393 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1394 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1395 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1396 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
1397 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
1399 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1400 GraphicsOutput
= Private
->GraphicsOutput
;
1401 UgaDraw
= Private
->UgaDraw
;
1402 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1404 GetTextColors (This
, &Foreground
, &Background
);
1405 if (GraphicsOutput
!= NULL
) {
1406 Status
= GraphicsOutput
->Blt (
1415 ModeData
->GopHeight
,
1419 Status
= UgaDraw
->Blt (
1421 (EFI_UGA_PIXEL
*) (UINTN
) &Background
,
1428 ModeData
->GopHeight
,
1433 This
->Mode
->CursorColumn
= 0;
1434 This
->Mode
->CursorRow
= 0;
1443 GraphicsConsoleConOutSetCursorPosition (
1444 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1449 Routine Description:
1451 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().
1455 This - Indicates the calling context.
1457 Column - The row to set cursor to.
1459 Row - The column to set cursor to.
1464 The operation completed successfully.
1467 The request fails due to Graphics Console device error.
1470 The Graphics Console is not in a valid text mode, or the cursor position
1471 is invalid for current mode.
1475 GRAPHICS_CONSOLE_DEV
*Private
;
1476 GRAPHICS_CONSOLE_MODE_DATA
*ModeData
;
1478 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1479 ModeData
= &(Private
->ModeData
[This
->Mode
->Mode
]);
1481 if ((Column
>= ModeData
->Columns
) || (Row
>= ModeData
->Rows
)) {
1482 return EFI_UNSUPPORTED
;
1485 if (((INT32
) Column
== This
->Mode
->CursorColumn
) && ((INT32
) Row
== This
->Mode
->CursorRow
)) {
1491 This
->Mode
->CursorColumn
= (INT32
) Column
;
1492 This
->Mode
->CursorRow
= (INT32
) Row
;
1501 GraphicsConsoleConOutEnableCursor (
1502 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1506 Routine Description:
1508 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
1509 In this driver, the cursor cannot be hidden.
1513 This - Indicates the calling context.
1515 Visible - If TRUE, the cursor is set to be visible,
1516 If FALSE, the cursor is set to be invisible.
1521 The request is valid.
1524 The Graphics Console does not support a hidden cursor.
1530 This
->Mode
->CursorVisible
= Visible
;
1539 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1540 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Foreground
,
1541 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Background
1546 Attribute
= This
->Mode
->Attribute
& 0x7F;
1548 *Foreground
= mEfiColors
[Attribute
& 0x0f];
1549 *Background
= mEfiColors
[Attribute
>> 4];
1555 DrawUnicodeWeightAtCursorN (
1556 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
,
1557 IN CHAR16
*UnicodeWeight
,
1561 GRAPHICS_CONSOLE_DEV
*Private
;
1563 EFI_STATUS ReturnStatus
;
1565 GLYPH_UNION GlyphData
;
1568 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1569 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1570 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
1571 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
1578 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1580 ReturnStatus
= EFI_SUCCESS
;
1584 GetTextColors (This
, &Foreground
, &Background
);
1588 while (Index
< Count
) {
1589 if (This
->Mode
->Attribute
& EFI_WIDE_ATTRIBUTE
) {
1590 GlyphStatus
= WIDE_CHAR
;
1592 GlyphStatus
= NARROW_CHAR
;
1595 Status
= mHii
->GetGlyph (
1603 if (EFI_ERROR (Status
)) {
1604 ReturnStatus
= Status
;
1609 CopyMem (&GlyphData
, Glyph
, sizeof (GLYPH_UNION
));
1613 // We are creating the second half of the wide character's BLT buffer
1615 if (GlyphWidth
== 0x10 && Counts
== 1) {
1616 CopyMem (&GlyphData
.NarrowGlyph
.GlyphCol1
, &Glyph
->WideGlyph
.GlyphCol2
, sizeof (Glyph
->WideGlyph
.GlyphCol2
));
1621 if (GlyphWidth
== 0x10) {
1624 (UINT8
*) &GlyphData
,
1630 &Private
->LineBuffer
[ArrayIndex
* GLYPH_WIDTH
]
1635 (UINT8
*) &GlyphData
,
1641 &Private
->LineBuffer
[ArrayIndex
* GLYPH_WIDTH
]
1647 } while (Counts
< 2 && GlyphWidth
== 0x10);
1651 // If we are printing Wide characters, treat the BLT as if it is twice as many characters
1653 if (GlyphWidth
== 0x10) {
1657 // Blt a character to the screen
1659 GlyphX
= This
->Mode
->CursorColumn
* GLYPH_WIDTH
;
1660 GlyphY
= This
->Mode
->CursorRow
* GLYPH_HEIGHT
;
1661 GraphicsOutput
= Private
->GraphicsOutput
;
1662 UgaDraw
= Private
->UgaDraw
;
1663 if (GraphicsOutput
!= NULL
) {
1664 GraphicsOutput
->Blt (
1666 Private
->LineBuffer
,
1667 EfiBltBufferToVideo
,
1670 GlyphX
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1671 GlyphY
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1672 GLYPH_WIDTH
* Count
,
1674 GLYPH_WIDTH
* Count
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1679 (EFI_UGA_PIXEL
*) (UINTN
) Private
->LineBuffer
,
1680 EfiUgaBltBufferToVideo
,
1683 GlyphX
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaX
,
1684 GlyphY
+ Private
->ModeData
[This
->Mode
->Mode
].DeltaY
,
1685 GLYPH_WIDTH
* Count
,
1687 GLYPH_WIDTH
* Count
* sizeof (EFI_UGA_PIXEL
)
1691 return ReturnStatus
;
1696 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*This
1699 GRAPHICS_CONSOLE_DEV
*Private
;
1700 EFI_SIMPLE_TEXT_OUTPUT_MODE
*CurrentMode
;
1703 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1704 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1705 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground
;
1706 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background
;
1707 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar
[GLYPH_HEIGHT
][GLYPH_WIDTH
];
1711 CurrentMode
= This
->Mode
;
1713 if (!CurrentMode
->CursorVisible
) {
1717 Private
= GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This
);
1718 GraphicsOutput
= Private
->GraphicsOutput
;
1719 UgaDraw
= Private
->UgaDraw
;
1722 // BUGBUG - we need to think about what to do with wide and narrow character deletions.
1725 // Blt a character to the screen
1727 GlyphX
= (CurrentMode
->CursorColumn
* GLYPH_WIDTH
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaX
;
1728 GlyphY
= (CurrentMode
->CursorRow
* GLYPH_HEIGHT
) + Private
->ModeData
[CurrentMode
->Mode
].DeltaY
;
1729 if (GraphicsOutput
!= NULL
) {
1730 GraphicsOutput
->Blt (
1732 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltChar
,
1733 EfiBltVideoToBltBuffer
,
1740 GLYPH_WIDTH
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1745 (EFI_UGA_PIXEL
*) (UINTN
) BltChar
,
1746 EfiUgaVideoToBltBuffer
,
1753 GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)
1757 GetTextColors (This
, &Foreground
.Pixel
, &Background
.Pixel
);
1760 // Convert Monochrome bitmap of the Glyph to BltBuffer structure
1762 for (Y
= 0; Y
< GLYPH_HEIGHT
; Y
++) {
1763 for (X
= 0; X
< GLYPH_WIDTH
; X
++) {
1764 if ((mCursorGlyph
.GlyphCol1
[Y
] & (1 << X
)) != 0) {
1765 BltChar
[Y
][GLYPH_WIDTH
- X
- 1].Raw
^= Foreground
.Raw
;
1770 if (GraphicsOutput
!= NULL
) {
1771 GraphicsOutput
->Blt (
1773 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltChar
,
1774 EfiBltBufferToVideo
,
1781 GLYPH_WIDTH
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1786 (EFI_UGA_PIXEL
*) (UINTN
) BltChar
,
1787 EfiUgaBltBufferToVideo
,
1794 GLYPH_WIDTH
* sizeof (EFI_UGA_PIXEL
)