windows-nt/Source/XPSP1/NT/base/boot/efi/efidisp.c
2020-09-26 16:20:57 +08:00

618 lines
11 KiB
C

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
efidisp.c
Author:
Create It. 21-Nov-2000 (andrewr)
Abstract:
This file contains utility routines for manipulating the EFI
SIMPLE_CONSOLE_OUTPUT interface
--*/
#include "bldr.h"
#include "bootefi.h"
#include "efi.h"
#include "efip.h"
#include "flop.h"
//
// Externals
//
extern EFI_HANDLE EfiImageHandle;
extern EFI_SYSTEM_TABLE *EfiST;
extern EFI_BOOT_SERVICES *EfiBS;
extern EFI_RUNTIME_SERVICES *EfiRS;
extern BOOLEAN GoneVirtual;
BOOLEAN gInverse = FALSE;
ULONG
BlEfiGetLinesPerRow(
VOID
)
/*++
Routine Description:
Gets the number of lines per EFI console row.
Arguments:
None.
Return Value:
ULONG - number of lines.
--*/
{
//
// TODO: read the modes to determine lines/row.
//
// for now we just support 80x25
//
return 25;
}
ULONG
BlEfiGetColumnsPerLine(
VOID
)
/*++
Routine Description:
Gets the number of columns per EFI console line.
Arguments:
None.
Return Value:
ULONG - number of columns.
--*/
{
//
// TODO: read the modes to determine columns/line.
//
// for now we just support 80x25
//
return 80;
}
BOOLEAN
BlEfiClearDisplay(
VOID
)
/*++
Routine Description:
Clears the display.
Arguments:
None.
Return Value:
BOOLEAN - TRUE if the call succeeded.
--*/
{
EFI_STATUS Status;
//
// you must be in physical mode to call EFI
//
FlipToPhysical();
Status = EfiST->ConOut->ClearScreen(EfiST->ConOut);
FlipToVirtual();
return (Status == EFI_SUCCESS);
}
BOOLEAN
BlEfiClearToEndOfDisplay(
VOID
)
/*++
Routine Description:
Clears from the current cursor position to the end of the display.
Arguments:
None.
Return Value:
BOOLEAN - TRUE if the call succeeded.
--*/
{
ULONG i,j, LinesPerRow,ColumnsPerLine;
BOOLEAN FirstTime = TRUE;
//
// you must be in physical mode to call EFI
//
FlipToPhysical();
LinesPerRow = BlEfiGetLinesPerRow();
ColumnsPerLine = BlEfiGetColumnsPerLine();
for (i = EfiST->ConOut->Mode->CursorRow; i<= LinesPerRow; i++) {
j = FirstTime
? EfiST->ConOut->Mode->CursorColumn
: 0 ;
FirstTime = FALSE;
for (; j <= ColumnsPerLine; j++) {
EfiST->ConOut->SetCursorPosition(
EfiST->ConOut,
i,
j);
//
// outputting a space should clear the current character
//
EfiST->ConOut->OutputString( EfiST->ConOut,
L" " );
}
}
//
// flip back into virtual mode and return
//
FlipToVirtual();
return(TRUE);
}
BOOLEAN
BlEfiClearToEndOfLine(
VOID
)
/*++
Routine Description:
Clears from the current cursor position to the end of the line.
Arguments:
None.
Return Value:
BOOLEAN - TRUE if the call succeeded.
--*/
{
ULONG i, ColumnsPerLine;
ULONG x, y;
ColumnsPerLine = BlEfiGetColumnsPerLine();
//
// save current cursor position
//
BlEfiGetCursorPosition( &x, &y );
FlipToPhysical();
for (i = EfiST->ConOut->Mode->CursorColumn; i <= ColumnsPerLine; i++) {
EfiST->ConOut->SetCursorPosition(
EfiST->ConOut,
i,
EfiST->ConOut->Mode->CursorRow);
//
// outputting a space should clear the current character
//
EfiST->ConOut->OutputString( EfiST->ConOut,
L" " );
}
//
// restore the current cursor position
//
EfiST->ConOut->SetCursorPosition(
EfiST->ConOut,
x,
y );
FlipToVirtual();
return(TRUE);
}
BOOLEAN
BlEfiGetCursorPosition(
OUT PULONG x, OPTIONAL
OUT PULONG y OPTIONAL
)
/*++
Routine Description:
retrieves the current cursor position
Arguments:
x - if specified, receives the current cursor column.
y - if specified, receives the current cursor row.
Return Value:
BOOLEAN - TRUE if the call succeeded.
--*/
{
FlipToPhysical();
if (x) {
*x = EfiST->ConOut->Mode->CursorColumn;
}
if (y) {
*y = EfiST->ConOut->Mode->CursorRow;
}
FlipToVirtual();
return(TRUE);
}
BOOLEAN
BlEfiPositionCursor(
IN ULONG Column,
IN ULONG Row
)
/*++
Routine Description:
Sets the current cursor position.
Arguments:
Column - column to set (x coordinate)
Row - row to set (y coordinate)
Return Value:
BOOLEAN - TRUE if the call succeeded.
--*/
{
EFI_STATUS Status;
FlipToPhysical();
Status = EfiST->ConOut->SetCursorPosition(EfiST->ConOut,Column,Row);
FlipToVirtual();
return (Status == EFI_SUCCESS);
}
BOOLEAN
BlEfiEnableCursor(
BOOLEAN bVisible
)
/*++
Routine Description:
Turns on or off the input cursor.
Arguments:
bVisible - TRUE indicates that the cursor should be made visible.
Return Value:
BOOLEAN - TRUE if the call succeeded.
--*/
{
EFI_STATUS Status;
FlipToPhysical();
Status = EfiST->ConOut->EnableCursor( EfiST->ConOut, bVisible );
FlipToVirtual();
return (Status == EFI_SUCCESS);
}
BOOLEAN
BlEfiSetAttribute(
ULONG Attribute
)
/*++
Routine Description:
Sets the current attribute for the console.
This routines switches between the ATT_* constants into the EFI_* display
constants. Not all of the ATT_ flags can be supported under EFI, so we
make a best guess.
Arguments:
None.
Return Value:
BOOLEAN - TRUE if the call succeeded.
--*/
{
EFI_STATUS Status;
UINTN foreground,background;
UINTN EfiAttribute;
switch (Attribute & 0xf) {
case ATT_FG_BLACK:
foreground = EFI_BLACK;
break;
case ATT_FG_RED:
foreground = EFI_RED;
break;
case ATT_FG_GREEN:
foreground = EFI_GREEN;
break;
case ATT_FG_YELLOW:
foreground = EFI_YELLOW;
break;
case ATT_FG_BLUE:
foreground = EFI_BLUE;
break;
case ATT_FG_MAGENTA:
foreground = EFI_MAGENTA;
break;
case ATT_FG_CYAN:
foreground = EFI_CYAN;
break;
case ATT_FG_WHITE:
foreground = EFI_LIGHTGRAY; // this is a best guess
break;
case ATT_FG_INTENSE:
foreground = EFI_WHITE; // this is a best guess
break;
default:
// you may fall into this for blinking attribute, etc.
foreground = EFI_WHITE;
}
switch ( Attribute & ( 0xf << 4)) {
case ATT_BG_BLACK:
background = EFI_BACKGROUND_BLACK;
break;
case ATT_BG_RED:
background = EFI_BACKGROUND_RED;
break;
case ATT_BG_GREEN:
background = EFI_BACKGROUND_GREEN;
break;
case ATT_BG_YELLOW:
// there is no yellow background in EFI
background = EFI_BACKGROUND_CYAN;
break;
case ATT_BG_BLUE:
background = EFI_BACKGROUND_BLUE;
break;
case ATT_BG_MAGENTA:
background = EFI_BACKGROUND_MAGENTA;
break;
case ATT_BG_CYAN:
background = EFI_BACKGROUND_CYAN;
break;
case ATT_BG_WHITE:
// there is no white background in EFI
background = EFI_BACKGROUND_LIGHTGRAY;
break;
case ATT_BG_INTENSE:
// there is no intense (or white) background in EFI
background = EFI_BACKGROUND_LIGHTGRAY;
break;
default:
background = EFI_BACKGROUND_LIGHTGRAY;
break;
}
EfiAttribute = foreground | background ;
FlipToPhysical();
Status = EfiST->ConOut->SetAttribute(EfiST->ConOut,EfiAttribute);
FlipToVirtual();
return (Status == EFI_SUCCESS);
}
BOOLEAN
BlEfiSetInverseMode(
BOOLEAN fInverseOn
)
/*++
Routine Description:
Sets the console text to an inverse attribute.
Since EFI doesn't support the concept of inverse, we have
to make a best guess at this. Note that if you clear the
display, etc., then the entire display will be set to this
attribute.
Arguments:
None.
Return Value:
BOOLEAN - TRUE if the call succeeded.
--*/
{
EFI_STATUS Status;
UINTN EfiAttribute,foreground,background;
//
// if it's already on, then just return.
//
if (fInverseOn && gInverse) {
return(TRUE);
}
//
// if it's already off, then just return.
//
if (!fInverseOn && !gInverse) {
return(TRUE);
}
FlipToPhysical();
//
// get the current attribute and switch it.
//
EfiAttribute = EfiST->ConOut->Mode->Attribute;
foreground = EfiAttribute & 0xf;
background = (EfiAttribute & 0xf0) >> 4 ;
EfiAttribute = background | foreground;
Status = EfiST->ConOut->SetAttribute(EfiST->ConOut,EfiAttribute);
FlipToVirtual();
gInverse = !gInverse;
return (Status == EFI_SUCCESS);
}
//
// Array of EFI drawing characters.
//
// This array MUST MATCH the GraphicsChar enumerated type in bldr.h.
//
USHORT EfiDrawingArray[GraphicsCharMax] = {
BOXDRAW_DOUBLE_DOWN_RIGHT,
BOXDRAW_DOUBLE_DOWN_LEFT,
BOXDRAW_DOUBLE_UP_RIGHT,
BOXDRAW_DOUBLE_UP_LEFT,
BOXDRAW_DOUBLE_VERTICAL,
BOXDRAW_DOUBLE_HORIZONTAL,
BLOCKELEMENT_FULL_BLOCK,
BLOCKELEMENT_LIGHT_SHADE
};
USHORT
BlEfiGetGraphicsChar(
IN GraphicsChar WhichOne
)
/*++
Routine Description:
Gets the appropriate mapping character.
Arguments:
GraphicsChar - enumerated type indicating character to be retrieved.
Return Value:
USHORT - EFI drawing character.
--*/
{
//
// just return a space if the input it out of range
//
if (WhichOne >= GraphicsCharMax) {
return(L' ');
}
return(EfiDrawingArray[WhichOne]);
}
#if DBG
VOID
DBG_EFI_PAUSE(
VOID
)
{
EFI_EVENT EventArray[2];
EFI_INPUT_KEY Key;
UINTN num;
if (GoneVirtual) {
FlipToPhysical();
}
EventArray[0] = EfiST->ConIn->WaitForKey;
EventArray[1] = NULL;
EfiBS->WaitForEvent(1,EventArray,&num);
//
// reset the event
//
EfiST->ConIn->ReadKeyStroke( EfiST->ConIn, &Key );
if (GoneVirtual) {
FlipToVirtual();
}
}
#else
VOID
DBG_EFI_PAUSE(
VOID
)
{
NOTHING;
}
#endif