877 lines
29 KiB
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);
|
|
}
|
|
}
|
|
|