consoleout.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 447 行
C
447 行
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
ConsoleOut.c
Abstract:
Console based on Win32 APIs.
This file creates an Win32 window and attaches a SimpleTextOut protocol.
--*/
#include "Console.h"
//
// Private worker functions.
//
STATIC
VOID
WinNtSimpleTextOutScrollScreen (
IN OUT WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Console
);
STATIC
VOID
WinNtSimpleTextOutPutChar (
IN OUT WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Console,
IN CHAR16 Char
);
//
// Modeule Global for Simple Text Out Mode.
//
#define MAX_SIMPLE_TEXT_OUT_MODE \
(sizeof(mWinNtSimpleTextOutSupportedModes)/sizeof(WIN_NT_SIMPLE_TEXT_OUT_MODE))
STATIC WIN_NT_SIMPLE_TEXT_OUT_MODE mWinNtSimpleTextOutSupportedModes[] = {
{ 80, 25 },
{ 80, 50 },
{ 80, 43 },
{ 100, 100 },
{ 100, 999 }
};
STATIC
EFI_STATUS
EFIAPI
WinNtSimpleTextOutReset (
IN struct _EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
{
WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;
Private = WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS(This);
//reset the background and keep the foreground unchanged
//
This->SetAttribute(This,This->Mode->Attribute & 0xf);
WinNtSimpleTextOutSetMode (This, 0);
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
EFIAPI
WinNtSimpleTextOutOutputString (
IN struct _EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN CHAR16 *String
)
{
WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;
CHAR16 *Str;
Private = WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS(This);
for (Str = String; *Str != '\0'; Str++) {
switch (*Str) {
case '\n':
if (Private->Possition.Y == (Private->MaxScreenSize.Y - 1)) {
WinNtSimpleTextOutScrollScreen (Private);
}
if (Private->Possition.Y < (Private->MaxScreenSize.Y - 1)) {
Private->Possition.Y++;
This->Mode->CursorRow++;
}
break;
case '\r':
Private->Possition.X = 0;
This->Mode->CursorColumn = 0;
break;
case '\b':
if (Private->Possition.X > 0) {
Private->Possition.X--;
This->Mode->CursorColumn--;
}
break;
default:
WinNtSimpleTextOutPutChar (Private, *Str);
}
}
return EFI_SUCCESS;
}
STATIC
VOID
WinNtSimpleTextOutPutChar (
IN OUT WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Console,
IN CHAR16 Char
)
{
SMALL_RECT Region;
COORD StrCoordinate;
COORD StrSize;
CHAR_INFO CharInfo;
BOOL Flag;
CharInfo.Char.UnicodeChar = Char;
CharInfo.Attributes = Console->Attribute;
StrSize.X = 1;
StrSize.Y = 1;
StrCoordinate.X = 0;
StrCoordinate.Y = 0;
Region.Left = (short int)Console->Possition.X;
Region.Top = (short int)Console->Possition.Y;
Region.Right = (short int)(Console->Possition.X + 1);
Region.Bottom = (short int)Console->Possition.Y;
Console->WinNtThunk->WriteConsoleOutput (
Console->NtOutHandle,
&CharInfo,
StrSize,
StrCoordinate,
&Region
);
if (Console->Possition.X >= (Console->MaxScreenSize.X - 1)) {
//
// If you print off the end wrap around
//
Console->SimpleTextOut.OutputString (&Console->SimpleTextOut, L"\n\r");
} else {
Console->Possition.X++;
Console->SimpleTextOut.Mode->CursorColumn++;
}
Flag = Console->WinNtThunk->SetConsoleCursorPosition (Console->NtOutHandle, Console->Possition);
}
STATIC
VOID
WinNtSimpleTextOutScrollScreen (
IN OUT WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Console
)
{
SMALL_RECT Scroll;
CHAR_INFO CharInfo;
COORD Origin;
CharInfo.Char.UnicodeChar = ' ';
CharInfo.Attributes = Console->Attribute;
Origin.X = 0;
Origin.Y = 0;
Scroll.Top = 1;
Scroll.Left = 0;
Scroll.Right = (short int)Console->MaxScreenSize.X;
Scroll.Bottom = (short int)Console->MaxScreenSize.Y;
Console->WinNtThunk->ScrollConsoleScreenBuffer (
Console->NtOutHandle,
&Scroll,
NULL,
Origin,
&CharInfo
);
}
STATIC
EFI_STATUS
EFIAPI
WinNtSimpleTextOutTestString (
IN struct _EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN CHAR16 *String
)
{
WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;
Private = WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS(This);
//
// BugBug: The correct answer would be a function of what code pages
// are currently loaded? For now we will just return success.
//
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
EFIAPI
WinNtSimpleTextOutQueryMode (
IN struct _EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN UINTN ModeNumber,
OUT UINTN *Columns,
OUT UINTN *Rows
)
{
WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;
Private = WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS(This);
if (ModeNumber > MAX_SIMPLE_TEXT_OUT_MODE) {
return EFI_INVALID_PARAMETER;
}
*Columns = mWinNtSimpleTextOutSupportedModes[ModeNumber].ColumnsX;
*Rows = mWinNtSimpleTextOutSupportedModes[ModeNumber].RowsY;
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
EFIAPI
WinNtSimpleTextOutSetMode (
IN struct _EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN UINTN ModeNumber
)
{
WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;
Private = WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS(This);
if (ModeNumber > MAX_SIMPLE_TEXT_OUT_MODE) {
return EFI_INVALID_PARAMETER;
}
Private->MaxScreenSize.X = (WORD)mWinNtSimpleTextOutSupportedModes[ModeNumber].ColumnsX;
Private->MaxScreenSize.Y = (WORD)mWinNtSimpleTextOutSupportedModes[ModeNumber].RowsY;
Private->WinNtThunk->SetConsoleScreenBufferSize (Private->NtOutHandle, Private->MaxScreenSize);
Private->WinNtThunk->SetConsoleActiveScreenBuffer (Private->NtOutHandle);
This->Mode->Mode = (INT32)ModeNumber;
This->EnableCursor (This, TRUE);
This->ClearScreen (This);
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
EFIAPI
WinNtSimpleTextOutSetAttribute (
IN struct _EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN UINTN Attribute
)
{
WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;
Private = WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS(This);
Private->Attribute = (WORD)Attribute;
This->Mode->Attribute = (INT32)Attribute;
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
EFIAPI
WinNtSimpleTextOutClearScreen (
IN struct _EFI_SIMPLE_TEXT_OUT_PROTOCOL *This
)
{
WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;
DWORD ConsoleWindow;
Private = WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS(This);
This->SetCursorPosition (This, 0, 0);
Private->WinNtThunk->FillConsoleOutputCharacter (
Private->NtOutHandle,
' ',
Private->MaxScreenSize.X * Private->MaxScreenSize.Y,
Private->Possition,
&ConsoleWindow
);
Private->WinNtThunk->FillConsoleOutputAttribute (
Private->NtOutHandle,
Private->Attribute,
Private->MaxScreenSize.X * Private->MaxScreenSize.Y,
Private->Possition,
&ConsoleWindow
);
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
EFIAPI
WinNtSimpleTextOutSetCursorPosition (
IN struct _EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN UINTN Column,
IN UINTN Row
)
{
WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;
Private = WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS(This);
Private->Possition.X = (WORD)Column;
This->Mode->CursorColumn = (INT32)Column;
Private->Possition.Y = (WORD)Row;
This->Mode->CursorRow = (INT32)Row;
Private->WinNtThunk->SetConsoleCursorPosition (Private->NtOutHandle, Private->Possition);
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
EFIAPI
WinNtSimpleTextOutEnableCursor (
IN struct _EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
IN BOOLEAN Enable
)
{
WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;
CONSOLE_CURSOR_INFO Info;
Private = WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS(This);
Private->CursorEnable = Enable;
This->Mode->CursorVisible = Enable;
Private->WinNtThunk->GetConsoleCursorInfo (Private->NtOutHandle, &Info);
Info.bVisible = Enable;
Private->WinNtThunk->SetConsoleCursorInfo (Private->NtOutHandle, &Info);
return EFI_SUCCESS;
}
EFI_STATUS
WinNtSimpleTextOutOpenWindow (
IN OUT WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private
)
{
EFI_SIMPLE_TEXT_OUT_PROTOCOL *SimpleTextOut;
CHAR16 *WindowName;
WindowName = Private->WinNtIo->EnvString;
Private->Attribute = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
if (*WindowName == '?') {
Private->Attribute = BACKGROUND_RED | FOREGROUND_INTENSITY |
FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN;
WindowName = L"EFI Emulator Error Console";
}
EfiLibAddUnicodeString (
"eng",
gWinNtConsoleComponentName.SupportedLanguages,
&Private->ControllerNameTable,
WindowName
);
//
// Fill in protocol member functions
//
SimpleTextOut = &Private->SimpleTextOut;
SimpleTextOut->Reset = WinNtSimpleTextOutReset;
SimpleTextOut->OutputString = WinNtSimpleTextOutOutputString;
SimpleTextOut->TestString = WinNtSimpleTextOutTestString;
SimpleTextOut->QueryMode = WinNtSimpleTextOutQueryMode;
SimpleTextOut->SetMode = WinNtSimpleTextOutSetMode;
SimpleTextOut->SetAttribute = WinNtSimpleTextOutSetAttribute;
SimpleTextOut->ClearScreen = WinNtSimpleTextOutClearScreen;
SimpleTextOut->SetCursorPosition = WinNtSimpleTextOutSetCursorPosition;
SimpleTextOut->EnableCursor = WinNtSimpleTextOutEnableCursor;
//
// Initialize SimpleTextOut protocol mode structure
//
SimpleTextOut->Mode = &Private->SimpleTextOutMode;
SimpleTextOut->Mode->MaxMode = MAX_SIMPLE_TEXT_OUT_MODE;
SimpleTextOut->Mode->Attribute = (INT32)Private->Attribute;
//
// Open the window an initialize it!
//
Private->NtOutHandle = Private->WinNtThunk->CreateConsoleScreenBuffer(
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL,
CONSOLE_TEXTMODE_BUFFER,
NULL
);
Private->WinNtThunk->SetConsoleTitle (WindowName);
return SimpleTextOut->SetMode (SimpleTextOut, 0);
}
EFI_STATUS
WinNtSimpleTextOutCloseWindow (
IN OUT WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Console
)
{
Console->WinNtThunk->CloseHandle (Console->NtOutHandle);
return EFI_SUCCESS;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?