alder_lake_bios/Insyde/InsydeCrPkg/TerminalDxe/TerminalConOutCommon.c

877 lines
29 KiB
C

/** @file
Implementation for common function.
;******************************************************************************
;* Copyright (c) 2012, Insyde Software Corp. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
#include "Terminal.h"
//
// This list is used to define the valid extend chars.
// It also provides a mapping from Unicode to PCANSI or
// ASCII. The ASCII mapping we just made up.
//
//
UNICODE_TO_CHAR mUnicodeToPcAnsiOrAscii[] = {
// EFI UNICODE, PcAnsi, ASCii, LineDraw Character
BOXDRAW_HORIZONTAL, 0xc4, L'-', 0x71,
BOXDRAW_VERTICAL, 0xb3, L'|', 0x78,
BOXDRAW_DOWN_RIGHT, 0xda, L'/', 0x6c,
BOXDRAW_DOWN_LEFT, 0xbf, L'\\', 0x6b,
BOXDRAW_UP_RIGHT, 0xc0, L'\\', 0x6d,
BOXDRAW_UP_LEFT, 0xd9, L'/', 0x6a,
BOXDRAW_VERTICAL_RIGHT, 0xc3, L'|', 0x74,
BOXDRAW_VERTICAL_LEFT, 0xb4, L'|', 0x75,
BOXDRAW_DOWN_HORIZONTAL, 0xc2, L'+', 0x77,
BOXDRAW_UP_HORIZONTAL, 0xc1, L'+', 0x76,
BOXDRAW_VERTICAL_HORIZONTAL, 0xc5, L'+', 0x6e,
BOXDRAW_DOUBLE_HORIZONTAL, 0xcd, L'-', 0x71,
BOXDRAW_DOUBLE_VERTICAL, 0xba, L'|', 0x78,
BOXDRAW_DOWN_RIGHT_DOUBLE, 0xd5, L'/', 0x6c,
BOXDRAW_DOWN_DOUBLE_RIGHT, 0xd6, L'/', 0x6c,
BOXDRAW_DOUBLE_DOWN_RIGHT, 0xc9, L'/', 0x6c,
BOXDRAW_DOWN_LEFT_DOUBLE, 0xb8, L'\\', 0x6b,
BOXDRAW_DOWN_DOUBLE_LEFT, 0xb7, L'\\', 0x6b,
BOXDRAW_DOUBLE_DOWN_LEFT, 0xbb, L'\\', 0x6b,
BOXDRAW_UP_RIGHT_DOUBLE, 0xd4, L'\\', 0x6d,
BOXDRAW_UP_DOUBLE_RIGHT, 0xd3, L'\\', 0x6d,
BOXDRAW_DOUBLE_UP_RIGHT, 0xc8, L'\\', 0x6d,
BOXDRAW_UP_LEFT_DOUBLE, 0xbe, L'/', 0x6a,
BOXDRAW_UP_DOUBLE_LEFT, 0xbd, L'/', 0x6a,
BOXDRAW_DOUBLE_UP_LEFT, 0xbc, L'/', 0x6a,
BOXDRAW_VERTICAL_RIGHT_DOUBLE, 0xc6, L'|', 0x74,
BOXDRAW_VERTICAL_DOUBLE_RIGHT, 0xc7, L'|', 0x74,
BOXDRAW_DOUBLE_VERTICAL_RIGHT, 0xcc, L'|', 0x74,
BOXDRAW_VERTICAL_LEFT_DOUBLE, 0xb5, L'|', 0x75,
BOXDRAW_VERTICAL_DOUBLE_LEFT, 0xb6, L'|', 0x75,
BOXDRAW_DOUBLE_VERTICAL_LEFT, 0xb9, L'|', 0x75,
BOXDRAW_DOWN_HORIZONTAL_DOUBLE, 0xd1, L'+', 0x77,
BOXDRAW_DOWN_DOUBLE_HORIZONTAL, 0xd2, L'+', 0x77,
BOXDRAW_DOUBLE_DOWN_HORIZONTAL, 0xcb, L'+', 0x77,
BOXDRAW_UP_HORIZONTAL_DOUBLE, 0xcf, L'+', 0x76,
BOXDRAW_UP_DOUBLE_HORIZONTAL, 0xd0, L'+', 0x76,
BOXDRAW_DOUBLE_UP_HORIZONTAL, 0xca, L'+', 0x76,
BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE, 0xd8, L'+', 0x6e,
BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL, 0xd7, L'+', 0x6e,
BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL, 0xce, L'+', 0x6e,
BLOCKELEMENT_FULL_BLOCK, 0xdb, L'*', 0x61,
BLOCKELEMENT_LIGHT_SHADE, 0xb0, L'+', 0x61,
GEOMETRICSHAPE_UP_TRIANGLE, 0x5E, L'^', 0x5e,
GEOMETRICSHAPE_RIGHT_TRIANGLE, 0x3E, L'>', 0x3e,
GEOMETRICSHAPE_DOWN_TRIANGLE, 0x76, L'v', 0x00, // Not in LineDraw Table
GEOMETRICSHAPE_LEFT_TRIANGLE, 0x3C, L'<', 0x3c,
ARROW_LEFT, 0x3c, L'<', 0x3c,
ARROW_UP, 0x5E, L'^', 0x5e,
ARROW_RIGHT, 0x3E, L'>', 0x3e,
ARROW_DOWN, 0x76, L'v', 0x00, // Not in LineDraw Table
0x0000, 0x00
};
//
// define the ESC sequence code map EFI scan code.
// It can map to scan code or a function.
// Map to function has not implement.
//
ESC_SEQUENCE_CODE gEscSequenceCode[] = {
// Reset function
TP_ALL_TYPE, 0, ESC_CODE_FUNC, FUNC_RESET, L"R\x1Br\x1BR",
TP_ALL_TYPE, 0, ESC_CODE_FUNC, FUNC_VIDEO, L"VID",
TP_ALL_TYPE, 0, ESC_CODE_FUNC, FUNC_SENSE, L"SEN",
TP_ALL_TYPE, 0, ESC_CODE_FUNC, FUNC_MANUAL_REFRESH, L"r",
TP_ALL_TYPE, 0, ESC_CODE_FUNC, FUNC_MANUAL_REFRESH, L"R",
TP_ALL_TYPE, 0, ESC_CODE_FUNC, FUNC_AUTO_REFRESH, L"[0n",
TP_ALL_TYPE, 0, ESC_CODE_FUNC, FUNC_AUTO_REFRESH, L"[c",
TP_ALL_TYPE, 0, ESC_CODE_FUNC, FUNC_CHARSET, L"CS",
TP_PCANSI, 0, ESC_CODE_FUNC, FUNC_NONVT100_ALTKEY, L"^A",
TP_ALL_TYPE, 0, ESC_CODE_FUNC, FUNC_CR_SRV_MANAGER, L"SV",
//
// 1 byte ESC sequence code
//
// VT100,PC-ANSI Function key F1 ~ F12
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F1, L"1",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F2, L"2",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F3, L"3",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F4, L"4",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F5, L"5",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F6, L"6",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F7, L"7",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F8, L"8",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F9, L"9",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F10, L"0",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F11, L"!",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F12, L"@",
// VT100,PC-ANSI keypad key
TP_ANSI_100, 0, ESC_CODE_EXTENTION, SCAN_HOME, L"h",
TP_ANSI_100, 0, ESC_CODE_EXTENTION, SCAN_END, L"k",
TP_ANSI_100, 0, ESC_CODE_EXTENTION, SCAN_INSERT, L"+",
TP_ANSI_100, 0, ESC_CODE_EXTENTION, SCAN_DELETE, L"-",
TP_ANSI_100, 0, ESC_CODE_EXTENTION, SCAN_PAGE_UP, L"?",
TP_ANSI_100, 0, ESC_CODE_EXTENTION, SCAN_PAGE_DOWN, L"/",
// Ctrl + key , These keys is conflict with ASCII. So, define a sequence code for it.
TP_ALL_TYPE, 0, ESC_CODE_CONTROL, 0x32, L"\x0d", // Ctrl + M
TP_ALL_TYPE, 0, ESC_CODE_CONTROL, 0x23, L"\x08", // Ctrl + H
TP_ALL_TYPE, 0, ESC_CODE_CONTROL, 0x17, L"\x09", // Ctrl + I
TP_ALL_TYPE, 0, ESC_CODE_CONTROL, 0x24, L"\x0a", // Ctrl + J
//
// 2 byte ESC sequence code
//
// Arrow key
TP_ALL_TYPE, 0, ESC_CODE_EXTENTION, SCAN_UP, L"[A",
TP_ALL_TYPE, 0, ESC_CODE_EXTENTION, SCAN_DOWN, L"[B",
TP_ALL_TYPE, 0, ESC_CODE_EXTENTION, SCAN_RIGHT, L"[C",
TP_ALL_TYPE, 0, ESC_CODE_EXTENTION, SCAN_LEFT, L"[D",
// VT100,PC-ANSI Function key F1 ~ F12
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F1, L"OP",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F2, L"OQ",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F3, L"OR",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F4, L"OS",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F5, L"OT",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F6, L"OU",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F7, L"OV",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F8, L"OW",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F9, L"OX",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F10, L"OY",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F11, L"OZ",
TP_ANSI_100, 0, ESC_CODE_SCANCODE, SCAN_F12, L"OA",
// PC-ANSI Function Key F1 ~ F12 (keys for SCO and Unix ANSI emulators)
TP_PCANSI, 0, ESC_CODE_SCANCODE, SCAN_F1, L"[M",
TP_PCANSI, 0, ESC_CODE_SCANCODE, SCAN_F2, L"[N",
TP_PCANSI, 0, ESC_CODE_SCANCODE, SCAN_F3, L"[O",
TP_PCANSI, 0, ESC_CODE_SCANCODE, SCAN_F4, L"[P",
TP_PCANSI, 0, ESC_CODE_SCANCODE, SCAN_F5, L"[Q",
TP_PCANSI, 0, ESC_CODE_SCANCODE, SCAN_F6, L"[R",
TP_PCANSI, 0, ESC_CODE_SCANCODE, SCAN_F7, L"[S",
TP_PCANSI, 0, ESC_CODE_SCANCODE, SCAN_F8, L"[T",
TP_PCANSI, 0, ESC_CODE_SCANCODE, SCAN_F9, L"[U",
TP_PCANSI, 0, ESC_CODE_SCANCODE, SCAN_F10, L"[V",
TP_PCANSI, 0, ESC_CODE_SCANCODE, SCAN_F11, L"[W",
TP_PCANSI, 0, ESC_CODE_SCANCODE, SCAN_F12, L"[X",
TP_PCANSI, 0, ESC_CODE_EXTENTION, SCAN_HOME, L"[H",
TP_PCANSI, 0, ESC_CODE_EXTENTION, SCAN_END, L"[K",
TP_PCANSI, 0, ESC_CODE_EXTENTION, SCAN_INSERT, L"[2",
TP_PCANSI, 0, ESC_CODE_EXTENTION, SCAN_DELETE, L"[3",
TP_PCANSI, 0, ESC_CODE_EXTENTION, SCAN_PAGE_UP, L"[5",
TP_PCANSI, 0, ESC_CODE_EXTENTION, SCAN_PAGE_DOWN, L"[6",
//
// 3 byte ESC sequence code
//
// Shit+TAB
TP_ALL_TYPE, 0, ESC_CODE_EXTENTION, SCAN_HOME, L"[0Z",
// Keypad home end ....
TP_ALL_TYPE, 0, ESC_CODE_EXTENTION, SCAN_HOME, L"[1~",
TP_ALL_TYPE, 0, ESC_CODE_EXTENTION, SCAN_END, L"[4~",
TP_ALL_TYPE, 0, ESC_CODE_EXTENTION, SCAN_INSERT, L"[2~",
TP_ALL_TYPE, 0, ESC_CODE_EXTENTION, SCAN_DELETE, L"[3~",
TP_ALL_TYPE, 0, ESC_CODE_EXTENTION, SCAN_PAGE_UP, L"[5~",
TP_ALL_TYPE, 0, ESC_CODE_EXTENTION, SCAN_PAGE_DOWN, L"[6~",
//
// 4 byte ESC sequence code
//
// VT100+ Function key F1 ~ F12
TP_100P_UTF8,0, ESC_CODE_SCANCODE, SCAN_F1, L"[11~",
TP_100P_UTF8,0, ESC_CODE_SCANCODE, SCAN_F2, L"[12~",
TP_100P_UTF8,0, ESC_CODE_SCANCODE, SCAN_F3, L"[13~",
TP_100P_UTF8,0, ESC_CODE_SCANCODE, SCAN_F4, L"[14~",
TP_100P_UTF8,0, ESC_CODE_SCANCODE, SCAN_F5, L"[15~",
TP_100P_UTF8,0, ESC_CODE_SCANCODE, SCAN_F6, L"[17~",
TP_100P_UTF8,0, ESC_CODE_SCANCODE, SCAN_F7, L"[18~",
TP_100P_UTF8,0, ESC_CODE_SCANCODE, SCAN_F8, L"[19~",
TP_100P_UTF8,0, ESC_CODE_SCANCODE, SCAN_F9, L"[20~",
TP_100P_UTF8,0, ESC_CODE_SCANCODE, SCAN_F10, L"[21~",
TP_100P_UTF8,0, ESC_CODE_SCANCODE, SCAN_F11, L"[23~",
TP_100P_UTF8,0, ESC_CODE_SCANCODE, SCAN_F12, L"[24~",
0,0, 0, 0, NULL
};
UINTN gEscSequenceCodeSize = sizeof(gEscSequenceCode);
EFI_TO_KB_SCANCODE_MAP gEfiToKbScanCodeMap[] = {
SCAN_UP, 0x48,
SCAN_DOWN, 0x50,
SCAN_RIGHT, 0x4D,
SCAN_LEFT, 0x4B,
SCAN_HOME, 0x47,
SCAN_END, 0x4F,
SCAN_INSERT, 0x52,
SCAN_DELETE, 0x53,
SCAN_PAGE_UP, 0x49,
SCAN_PAGE_DOWN, 0x51,
SCAN_F1, 0x3B,
SCAN_F2, 0x3C,
SCAN_F3, 0x3D,
SCAN_F4, 0x3E,
SCAN_F5, 0x3F,
SCAN_F6, 0x40,
SCAN_F7, 0x41,
SCAN_F8, 0x42,
SCAN_F9, 0x43,
SCAN_F10, 0x44,
SCAN_F11, 0x57,
SCAN_F12, 0x58,
SCAN_ESC, 0x01,
0, 0x00
};
UINT16 gUniCodeToKbScanCodeMap[][3] = {
// Unicode // KbScan
{'0', '0', 0x0B,},
{'1', '1', 0x02,},
{'2', '2', 0x03,},
{'3', '3', 0x04,},
{'4', '4', 0x05,},
{'5', '5', 0x06,},
{'6', '6', 0x07,},
{'7', '7', 0x08,},
{'8', '8', 0x09,},
{'9', '9', 0x0A,},
{'a', 'A', 0x1E,},
{'b', 'B', 0x30,},
{'c', 'C', 0x2E,},
{'d', 'D', 0x20,},
{'e', 'E', 0x12,},
{'f', 'F', 0x21,},
{'g', 'G', 0x22,},
{'h', 'H', 0x23,},
{'i', 'I', 0x17,},
{'j', 'J', 0x24,},
{'k', 'K', 0x25,},
{'l', 'L', 0x26,},
{'m', 'M', 0x32,},
{'n', 'N', 0x31,},
{'o', 'O', 0x18,},
{'p', 'P', 0x19,},
{'q', 'Q', 0x10,},
{'r', 'R', 0x13,},
{'s', 'S', 0x1F,},
{'t', 'T', 0x14,},
{'u', 'U', 0x16,},
{'v', 'V', 0x2F,},
{'w', 'W', 0x11,},
{'x', 'X', 0x2D,},
{'y', 'Y', 0x15,},
{'z', 'Z', 0x2C,},
{0}
};
CR_SPECIAL_COMMAND gCrSpecialCommand[] = {
//{L"\x1f", TYPE_FUNCTION_ID, FUNC_RESET}, // Press Ctrl+Shift+ '-' do a System Reset
{ 0, 0, 0}
};
UINTN gCrSpecialCommandSize = sizeof(gCrSpecialCommand);
BAUDRATE_DATA_LIMIT_TABLE gBaudRateDataAmountTable[] = {
1200, 50,
2400, 50,
4800, 50,
9600, 100,
19200, 100,
38400, 250,
57600, 500,
115200, 1000,
0, 0
};
CHAR16 gSetModeString[] = { ESC, '[', '8', ';', '0', '0', '0', ';', '0', '0', '0', 't', 0 };
CHAR16 gSetAttributeString[] = { ESC, '[', '0', 'm', ESC, '[', '4', '0', 'm', ESC, '[', '4', '0', 'm', 0 };
CHAR16 gClearScreenString[] = { ESC, '[', '2', 'J', 0 };
CHAR16 gSetCursorPositionString[] = { ESC, '[', '0', '0', '0', ';', '0', '0', '0', 'H', 0 };
CHAR16 gSetCharSetString[] = { ESC, '(', 'B', 0};
CHAR16 gEraseLine[] = { ESC, '[', '2', 'K', 0 };
CHAR16 gResetDeviceString[] = { ESC, 'c', 0};
CHAR16 gDiableAutoWrapString[] = { ESC, '[', '?', '7', 'l', 0};
CHAR16 gGetTermStatusString[] = { ESC, '[', '5', 'n', 0};
CHAR16 gSetCursorToLastRowStr[] = { ESC, '[', '8', '0', ';', '0', '0', 'H', 0 };
CHAR16 gScrollDownStr[] = { ESC, 'D', 0 };
extern CR_POLICY_VARIABLE *mCrPolicyVar;
extern UINT8 mTerminalMode;
extern BOOLEAN gEscProcess = FALSE;
//
// Body of the ConOut functions
//
/**
Detects if a Unicode char is for Box Drawing text graphics.
@param Graphic Unicode char to test.
@param PcAnsi Optional pointer to return PCANSI equivalent of Graphic.
@param Ascii Optional pointer to return ASCII equivalent of Graphic.
@param LineDrawChar Optional pointer to return LineDraw Character Set equivalent of Graphic.
if value is 0x00 means not matched character
@retval TRUE if Graphic is a supported Unicode Box Drawing character.
**/
BOOLEAN
TerminalIsValidTextGraphics (
IN CHAR16 Graphic,
OUT CHAR8 *PcAnsi, OPTIONAL
OUT CHAR8 *Ascii, OPTIONAL
OUT CHAR8 *LineDrawChar OPTIONAL
)
{
UNICODE_TO_CHAR *Table;
if ((((Graphic & 0xff00) != 0x2500) && ((Graphic & 0xff00) != 0x2100))) {
//
// Unicode drawing code charts are all in the 0x25xx range,
// arrows are 0x21xx
//
return FALSE;
}
for (Table = mUnicodeToPcAnsiOrAscii; Table->Unicode != 0x0000; Table++) {
if (Graphic == Table->Unicode) {
if (PcAnsi != NULL) {
*PcAnsi = Table->PcAnsi;
}
if (Ascii != NULL) {
*Ascii = Table->Ascii;
}
if (LineDrawChar != NULL) {
*LineDrawChar = Table->LineDrawChar;
}
return TRUE;
}
}
return FALSE;
}
/**
Confirm input ascii is valid for terminal
@param Ascii Unicode char to test.
@retval TRUE Input ascii is valid.
**/
BOOLEAN
TerminalIsValidAscii (
IN CHAR16 Ascii
)
{
//
// valid ascii code lies in the extent of 0x20 ~ 0x7f
//
if ((Ascii >= 0x20) && (Ascii <= 0x7f)) {
return TRUE;
}
return FALSE;
}
/**
Confirm input control character is valid for terminal
@param CharC Control character.
@retval TRUE Input character is valid.
**/
BOOLEAN
TerminalIsValidEfiCntlChar (
IN CHAR16 CharC
)
{
//
// only support four control characters.
//
if (CharC == CHAR_NULL ||
CharC == CHAR_BACKSPACE ||
CharC == CHAR_LINEFEED ||
CharC == CHAR_CARRIAGE_RETURN ||
CharC == CHAR_TAB
) {
return TRUE;
}
return FALSE;
}
/**
Output ESC sequence string without RefreshScreen event interrupt.
@param This Pointer to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
@param EscString Pointer to output EscString buffer
@retval EFI_SUCCESS The string is output successfully.
@retval EFI_DEVICE_ERROR The serial port fails to send the string out.
@retval EFI_WARN_UNKNOWN_GLYPH Indicates that some of the characters in the Unicode
string could not be rendered and are skipped.
**/
EFI_STATUS
OutputEscSquenceString (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN CHAR16 *EscString
)
{
TERMINAL_DEV *TerminalDevice;
EFI_STATUS Status;
EFI_TEXT_STRING TerminalOutputString;
//
// get Terminal device data structure pointer.
//
TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
if (TerminalDevice->TerminalType == LOGTERMTYPE) {
//
// Don't output ESC sequence,
// but return success status to ensure the caller function can work properly.
//
return EFI_SUCCESS;
}
if (mTerminalMode == ASYNC) {
TerminalOutputString = &PrivateOutputString;
} else {
TerminalOutputString = This->OutputString;
}
//
// Avoid send ESC command be interrupt
//
gEscProcess = TRUE;
TerminalDevice->OutputEscChar = TRUE;
Status = TerminalOutputString (This, EscString);
TerminalDevice->OutputEscChar = FALSE;
gEscProcess = FALSE;
return Status;
}
/**
Set the terminal to a specified display mode the same with screen mode.
@param This Indicates the calling context.
@param ModeNumber The text mode to set.
@retval EFI_SUCCESS The requested text mode is set.
@retval EFI_DEVICE_ERROR The requested text mode cannot be set
because of serial device error.
@retval EFI_UNSUPPORTED The text mode number is not valid.
**/
EFI_STATUS
AdjustTerminalResolution (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN UINTN ModeNumber
)
{
EFI_STATUS Status;
TERMINAL_DEV *TerminalDevice;
UINTN Columns;
UINTN Rows;
if (mCrPolicyVar->Feature.Bit.CRTerminalResize == FALSE) {
return EFI_SUCCESS;
}
//
// get Terminal device data structure pointer.
//
TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
Status = This->QueryMode (This, ModeNumber, &Columns, &Rows);
if (EFI_ERROR(Status)) {
return Status;
}
//
// control sequence to move the cursor
//
gSetModeString[MODE_ROW_OFFSET + 0] = (CHAR16) ('0' + (Rows / 100));
Rows %= 100;
gSetModeString[MODE_ROW_OFFSET + 1] = (CHAR16) ('0' + (Rows / 10));
Rows %= 10;
gSetModeString[MODE_ROW_OFFSET + 2] = (CHAR16) ('0' + Rows);
gSetModeString[MODE_COLUMN_OFFSET + 0] = (CHAR16) ('0' + (Columns / 100));
Columns %= 100;
gSetModeString[MODE_COLUMN_OFFSET + 1] = (CHAR16) ('0' + (Columns / 10));
Columns %= 10;
gSetModeString[MODE_COLUMN_OFFSET + 2] = (CHAR16) ('0' + Columns);
return OutputEscSquenceString (This, gSetModeString);
}
/**
Switch terminal character set.
@param This Pointer to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
@param CharSet The expected character set to switch
@retval EFI_SUCCESS The requested character set is update.
@retval EFI_DEVICE_ERROR The requested character set cannot be set due to serial port error.
@retval EFI_UNSUPPORTED The character set requested is not defined by EFI spec.
**/
EFI_STATUS
Vt100PlusSwitchCharSet (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN VT100_CHARACTER_SET CharSet
)
{
EFI_STATUS Status;
TERMINAL_DEV *TerminalDevice;
TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
//
// Normal ASCii table
//
Status = EFI_SUCCESS;
if (CharSet == VT100_ASCII_CHAR_SET) {
if (TerminalDevice->Vt100CurrentCharSet != VT100_ASCII_CHAR_SET) {
TerminalDevice->Vt100CurrentCharSet = VT100_ASCII_CHAR_SET;
gSetCharSetString[2] = L'B';
Status = OutputEscSquenceString (
This,
gSetCharSetString
);
}
}
//
// Special drawing character set
//
else if (CharSet == VT100_GRAPH_CHAR_SET) {
if (TerminalDevice->Vt100CurrentCharSet != VT100_GRAPH_CHAR_SET) {
TerminalDevice->Vt100CurrentCharSet = VT100_GRAPH_CHAR_SET;
gSetCharSetString[2] = L'0';
Status = OutputEscSquenceString (
This,
gSetCharSetString
);
}
} else {
Status = EFI_UNSUPPORTED;
}
return Status;
}
/**
Is graphic character support in Line Draw char set.
@param LineDrawChar The graphic character in Line Draw Table.
@retval TRUE LineDrawChar support.
@retval FALSE LineDrawChar not support.
**/
BOOLEAN
InLineDrawTable (
CHAR8 LineDrawChar
)
{
if (LineDrawChar == 0) {
return FALSE;
} else {
return TRUE;
}
}
/**
Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.Reset().
If ExtendeVerification is TRUE, then perform dependent serial device reset,
and set display mode to mode 0.
If ExtendedVerification is FALSE, only set display mode to mode 0.
@param This Indicates the calling context.
@param ExtendedVerification Indicates that the driver may perform a more
exhaustive verification operation of the device
during reset.
@retval EFI_SUCCESS The reset operation succeeds.
@retval EFI_DEVICE_ERROR The terminal is not functioning correctly or the serial port reset fails.
**/
EFI_STATUS
EFIAPI
CommonConOutReset (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
{
if (mTerminalMode == SYNC) {
return SyncTerminalConOutReset (This,ExtendedVerification);
} else {
return AsyncTerminalConOutReset (This,ExtendedVerification);
}
}
/**
Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString().
The Unicode string will be converted to terminal expressible data stream
and send to terminal via serial port.
@param This Indicates the calling context.
@param WString The Null-terminated Unicode string to be displayed
on the terminal screen.
@retval EFI_SUCCESS The string is output successfully.
@retval EFI_DEVICE_ERROR The serial port fails to send the string out.
@retval EFI_WARN_UNKNOWN_GLYPH Indicates that some of the characters in the Unicode string could not
be rendered and are skipped.
@retval EFI_UNSUPPORTED If current display mode is out of range.
**/
EFI_STATUS
EFIAPI
CommonConOutOutputString (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN CHAR16 *WString
)
{
if (mTerminalMode == SYNC) {
return SyncTerminalConOutOutputString (This, WString);
} else {
return AsyncTerminalConOutOutputString (This, WString);
}
}
/**
Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.TestString().
If one of the characters in the *Wstring is
neither valid Unicode drawing characters,
not ASCII code, then this function will return
EFI_UNSUPPORTED.
@param This Indicates the calling context.
@param WString The Null-terminated Unicode string to be tested.
@retval EFI_SUCCESS The terminal is capable of rendering the output string.
@retval EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be rendered.
**/
EFI_STATUS
EFIAPI
CommonConOutTestString (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN CHAR16 *WString
)
{
if (mTerminalMode == SYNC) {
return SyncTerminalConOutTestString (This, WString);
} else {
return AsyncTerminalConOutTestString (This, WString);
}
}
/**
Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.QueryMode().
It returns information for an available text mode
that the terminal supports.
@param This Indicates the calling context.
@param ModeNumber The mode number to return information on.
@param Columns The returned columns of the requested mode.
@param Rows The returned rows of the requested mode.
@retval EFI_SUCCESS The requested mode information is returned.
@retval EFI_UNSUPPORTED The mode number is not valid.
**/
EFI_STATUS
EFIAPI
CommonConOutQueryMode (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN UINTN ModeNumber,
OUT UINTN *Columns,
OUT UINTN *Rows
)
{
if (mTerminalMode == SYNC) {
return SyncTerminalConOutQueryMode (This, ModeNumber, Columns, Rows);
} else {
return AsyncTerminalConOutQueryMode (This, ModeNumber, Columns, Rows);
}
}
/**
Implements EFI_SIMPLE_TEXT_OUT.SetMode().
Set the terminal to a specified display mode.
In this driver, we only support mode 0.
@param This Indicates the calling context.
@param ModeNumber The text mode to set.
@retval EFI_SUCCESS The requested text mode is set.
@retval EFI_DEVICE_ERROR The requested text mode cannot be set
because of serial device error.
@retval EFI_UNSUPPORTED The text mode number is not valid.
**/
EFI_STATUS
EFIAPI
CommonConOutSetMode (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN UINTN ModeNumber
)
{
if (mTerminalMode == SYNC) {
return SyncTerminalConOutSetMode (This, ModeNumber);
} else {
return AsyncTerminalConOutSetMode (This, ModeNumber);
}
}
/**
Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetAttribute().
@param This Indicates the calling context.
@param Attribute The attribute to set. Only bit0..6 are valid, all other bits
are undefined and must be zero.
@retval EFI_SUCCESS The requested attribute is set.
@retval EFI_DEVICE_ERROR The requested attribute cannot be set due to serial port error.
@retval EFI_UNSUPPORTED The attribute requested is not defined by EFI spec.
**/
EFI_STATUS
EFIAPI
CommonConOutSetAttribute (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN UINTN Attribute
)
{
if (mTerminalMode == SYNC) {
return SyncTerminalConOutSetAttribute (This, Attribute);
} else {
return AsyncTerminalConOutSetAttribute (This, Attribute);
}
}
/**
Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.ClearScreen().
It clears the ANSI terminal's display to the
currently selected background color.
@param This Indicates the calling context.
@retval EFI_SUCCESS The operation completed successfully.
@retval EFI_DEVICE_ERROR The terminal screen cannot be cleared due to serial port error.
@retval EFI_UNSUPPORTED The terminal is not in a valid display mode.
**/
EFI_STATUS
EFIAPI
CommonConOutClearScreen (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
)
{
if (mTerminalMode == SYNC) {
return SyncTerminalConOutClearScreen (This);
} else {
return AsyncTerminalConOutClearScreen (This);
}
}
/**
Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetCursorPosition().
@param This Indicates the calling context.
@param Column The row to set cursor to.
@param Row The column to set cursor to.
@retval EFI_SUCCESS The operation completed successfully.
@retval EFI_DEVICE_ERROR The request fails due to serial port error.
@retval EFI_UNSUPPORTED The terminal is not in a valid text mode, or the cursor position
is invalid for current mode.
**/
EFI_STATUS
EFIAPI
CommonConOutSetCursorPosition (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN UINTN Column,
IN UINTN Row
)
{
if (mTerminalMode == SYNC) {
return SyncTerminalConOutSetCursorPosition (This, Column, Row);
} else {
return AsyncTerminalConOutSetCursorPosition (This, Column, Row);
}
}
/**
Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
In this driver, the cursor cannot be hidden.
@param This Indicates the calling context.
@param Visible If TRUE, the cursor is set to be visible,
If FALSE, the cursor is set to be invisible.
@retval EFI_SUCCESS The request is valid.
@retval EFI_UNSUPPORTED The terminal does not support cursor hidden.
**/
EFI_STATUS
EFIAPI
CommonConOutEnableCursor (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN BOOLEAN Visible
)
{
if (mTerminalMode == SYNC) {
return SyncTerminalConOutEnableCursor (This, Visible);
} else {
return AsyncTerminalConOutEnableCursor (This, Visible);
}
}