/** @file Implementation for EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL protocol. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
Copyright (C) 2016 Silicon Graphics, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #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 UnicodeToPcAnsiOrAscii[] = { { BOXDRAW_HORIZONTAL, 0xc4, L'-' }, { BOXDRAW_VERTICAL, 0xb3, L'|' }, { BOXDRAW_DOWN_RIGHT, 0xda, L'/' }, { BOXDRAW_DOWN_LEFT, 0xbf, L'\\' }, { BOXDRAW_UP_RIGHT, 0xc0, L'\\' }, { BOXDRAW_UP_LEFT, 0xd9, L'/' }, { BOXDRAW_VERTICAL_RIGHT, 0xc3, L'|' }, { BOXDRAW_VERTICAL_LEFT, 0xb4, L'|' }, { BOXDRAW_DOWN_HORIZONTAL, 0xc2, L'+' }, { BOXDRAW_UP_HORIZONTAL, 0xc1, L'+' }, { BOXDRAW_VERTICAL_HORIZONTAL, 0xc5, L'+' }, { BOXDRAW_DOUBLE_HORIZONTAL, 0xcd, L'-' }, { BOXDRAW_DOUBLE_VERTICAL, 0xba, L'|' }, { BOXDRAW_DOWN_RIGHT_DOUBLE, 0xd5, L'/' }, { BOXDRAW_DOWN_DOUBLE_RIGHT, 0xd6, L'/' }, { BOXDRAW_DOUBLE_DOWN_RIGHT, 0xc9, L'/' }, { BOXDRAW_DOWN_LEFT_DOUBLE, 0xb8, L'\\' }, { BOXDRAW_DOWN_DOUBLE_LEFT, 0xb7, L'\\' }, { BOXDRAW_DOUBLE_DOWN_LEFT, 0xbb, L'\\' }, { BOXDRAW_UP_RIGHT_DOUBLE, 0xd4, L'\\' }, { BOXDRAW_UP_DOUBLE_RIGHT, 0xd3, L'\\' }, { BOXDRAW_DOUBLE_UP_RIGHT, 0xc8, L'\\' }, { BOXDRAW_UP_LEFT_DOUBLE, 0xbe, L'/' }, { BOXDRAW_UP_DOUBLE_LEFT, 0xbd, L'/' }, { BOXDRAW_DOUBLE_UP_LEFT, 0xbc, L'/' }, { BOXDRAW_VERTICAL_RIGHT_DOUBLE, 0xc6, L'|' }, { BOXDRAW_VERTICAL_DOUBLE_RIGHT, 0xc7, L'|' }, { BOXDRAW_DOUBLE_VERTICAL_RIGHT, 0xcc, L'|' }, { BOXDRAW_VERTICAL_LEFT_DOUBLE, 0xb5, L'|' }, { BOXDRAW_VERTICAL_DOUBLE_LEFT, 0xb6, L'|' }, { BOXDRAW_DOUBLE_VERTICAL_LEFT, 0xb9, L'|' }, { BOXDRAW_DOWN_HORIZONTAL_DOUBLE, 0xd1, L'+' }, { BOXDRAW_DOWN_DOUBLE_HORIZONTAL, 0xd2, L'+' }, { BOXDRAW_DOUBLE_DOWN_HORIZONTAL, 0xcb, L'+' }, { BOXDRAW_UP_HORIZONTAL_DOUBLE, 0xcf, L'+' }, { BOXDRAW_UP_DOUBLE_HORIZONTAL, 0xd0, L'+' }, { BOXDRAW_DOUBLE_UP_HORIZONTAL, 0xca, L'+' }, { BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE, 0xd8, L'+' }, { BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL, 0xd7, L'+' }, { BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL, 0xce, L'+' }, { BLOCKELEMENT_FULL_BLOCK, 0xdb, L'*' }, { BLOCKELEMENT_LIGHT_SHADE, 0xb0, L'+' }, { GEOMETRICSHAPE_UP_TRIANGLE, '^', L'^' }, { GEOMETRICSHAPE_RIGHT_TRIANGLE, '>', L'>' }, { GEOMETRICSHAPE_DOWN_TRIANGLE, 'v', L'v' }, { GEOMETRICSHAPE_LEFT_TRIANGLE, '<', L'<' }, { ARROW_LEFT, '<', L'<' }, { ARROW_UP, '^', L'^' }, { ARROW_RIGHT, '>', L'>' }, { ARROW_DOWN, 'v', L'v' }, { 0x0000, 0x00, L'\0' } }; CHAR16 mSetModeString[] = { ESC, '[', '=', '3', 'h', 0 }; CHAR16 mSetAttributeString[] = { ESC, '[', '0', 'm', ESC, '[', '4', '0', 'm', ESC, '[', '4', '0', 'm', 0 }; CHAR16 mClearScreenString[] = { ESC, '[', '2', 'J', 0 }; CHAR16 mSetCursorPositionString[] = { ESC, '[', '0', '0', ';', '0', '0', 'H', 0 }; CHAR16 mCursorForwardString[] = { ESC, '[', '0', '0', 'C', 0 }; CHAR16 mCursorBackwardString[] = { ESC, '[', '0', '0', 'D', 0 }; // // Body of the ConOut functions // /** 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 TerminalConOutReset ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN BOOLEAN ExtendedVerification ) { EFI_STATUS Status; TERMINAL_DEV *TerminalDevice; TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This); // // Perform a more exhaustive reset by resetting the serial port. // if (ExtendedVerification) { // // Report progress code here // REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_PC_RESET), TerminalDevice->DevicePath ); Status = TerminalDevice->SerialIo->Reset (TerminalDevice->SerialIo); if (EFI_ERROR (Status)) { // // Report error code here // REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_ERROR_CODE | EFI_ERROR_MINOR, (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_CONTROLLER_ERROR), TerminalDevice->DevicePath ); return Status; } } This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BLACK)); Status = This->SetMode (This, 0); return Status; } /** 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 TerminalConOutOutputString ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN CHAR16 *WString ) { TERMINAL_DEV *TerminalDevice; EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode; UINTN MaxColumn; UINTN MaxRow; UINTN Length; UTF8_CHAR Utf8Char; CHAR8 GraphicChar; CHAR8 AsciiChar; EFI_STATUS Status; UINT8 ValidBytes; CHAR8 CrLfStr[2]; // // flag used to indicate whether condition happens which will cause // return EFI_WARN_UNKNOWN_GLYPH // BOOLEAN Warning; ValidBytes = 0; Warning = FALSE; AsciiChar = 0; // // get Terminal device data structure pointer. // TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This); // // Get current display mode // Mode = This->Mode; if (Mode->Mode >= Mode->MaxMode) { return EFI_UNSUPPORTED; } This->QueryMode ( This, Mode->Mode, &MaxColumn, &MaxRow ); for ( ; *WString != CHAR_NULL; WString++) { switch (TerminalDevice->TerminalType) { case TerminalTypePcAnsi: case TerminalTypeVt100: case TerminalTypeVt100Plus: case TerminalTypeTtyTerm: case TerminalTypeLinux: case TerminalTypeXtermR6: case TerminalTypeVt400: case TerminalTypeSCO: if (!TerminalIsValidTextGraphics (*WString, &GraphicChar, &AsciiChar)) { // // If it's not a graphic character convert Unicode to ASCII. // GraphicChar = (CHAR8)*WString; if (!(TerminalIsValidAscii (GraphicChar) || TerminalIsValidEfiCntlChar (GraphicChar))) { // // when this driver use the OutputString to output control string, // TerminalDevice->OutputEscChar is set to let the Esc char // to be output to the terminal emulation software. // if ((GraphicChar == 27) && TerminalDevice->OutputEscChar) { GraphicChar = 27; } else { GraphicChar = '?'; Warning = TRUE; } } AsciiChar = GraphicChar; } if (TerminalDevice->TerminalType != TerminalTypePcAnsi) { GraphicChar = AsciiChar; } Length = 1; Status = TerminalDevice->SerialIo->Write ( TerminalDevice->SerialIo, &Length, &GraphicChar ); if (EFI_ERROR (Status)) { goto OutputError; } break; case TerminalTypeVtUtf8: UnicodeToUtf8 (*WString, &Utf8Char, &ValidBytes); Length = ValidBytes; Status = TerminalDevice->SerialIo->Write ( TerminalDevice->SerialIo, &Length, (UINT8 *)&Utf8Char ); if (EFI_ERROR (Status)) { goto OutputError; } break; } // // Update cursor position. // switch (*WString) { case CHAR_BACKSPACE: if (Mode->CursorColumn > 0) { Mode->CursorColumn--; } break; case CHAR_LINEFEED: if (Mode->CursorRow < (INT32)(MaxRow - 1)) { Mode->CursorRow++; } break; case CHAR_CARRIAGE_RETURN: Mode->CursorColumn = 0; break; default: if (Mode->CursorColumn < (INT32)(MaxColumn - 1)) { Mode->CursorColumn++; } else { Mode->CursorColumn = 0; if (Mode->CursorRow < (INT32)(MaxRow - 1)) { Mode->CursorRow++; } if ((TerminalDevice->TerminalType == TerminalTypeTtyTerm) && !TerminalDevice->OutputEscChar) { // // We've written the last character on the line. The // terminal doesn't actually wrap its cursor until we print // the next character, but the driver thinks it has wrapped // already. Print CR LF to synchronize the terminal with // the driver, but only if we're not in the middle of // printing an escape sequence. // CrLfStr[0] = '\r'; CrLfStr[1] = '\n'; Length = sizeof (CrLfStr); Status = TerminalDevice->SerialIo->Write ( TerminalDevice->SerialIo, &Length, CrLfStr ); if (EFI_ERROR (Status)) { goto OutputError; } } } break; } } if (Warning) { return EFI_WARN_UNKNOWN_GLYPH; } return EFI_SUCCESS; OutputError: REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_ERROR_CODE | EFI_ERROR_MINOR, (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_OUTPUT_ERROR), TerminalDevice->DevicePath ); return EFI_DEVICE_ERROR; } /** 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 TerminalConOutTestString ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN CHAR16 *WString ) { TERMINAL_DEV *TerminalDevice; EFI_STATUS Status; // // get Terminal device data structure pointer. // TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This); switch (TerminalDevice->TerminalType) { case TerminalTypePcAnsi: case TerminalTypeVt100: case TerminalTypeVt100Plus: case TerminalTypeTtyTerm: Status = AnsiTestString (TerminalDevice, WString); break; case TerminalTypeVtUtf8: Status = VTUTF8TestString (TerminalDevice, WString); break; default: Status = EFI_UNSUPPORTED; break; } return Status; } /** 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 TerminalConOutQueryMode ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN ModeNumber, OUT UINTN *Columns, OUT UINTN *Rows ) { TERMINAL_DEV *TerminalDevice; if (ModeNumber >= (UINTN)This->Mode->MaxMode) { return EFI_UNSUPPORTED; } // // Get Terminal device data structure pointer. // TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This); *Columns = TerminalDevice->TerminalConsoleModeData[ModeNumber].Columns; *Rows = TerminalDevice->TerminalConsoleModeData[ModeNumber].Rows; return EFI_SUCCESS; } /** 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 TerminalConOutSetMode ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN ModeNumber ) { EFI_STATUS Status; TERMINAL_DEV *TerminalDevice; // // get Terminal device data structure pointer. // TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This); if (ModeNumber >= (UINTN)This->Mode->MaxMode) { return EFI_UNSUPPORTED; } // // Set the current mode // This->Mode->Mode = (INT32)ModeNumber; This->ClearScreen (This); TerminalDevice->OutputEscChar = TRUE; Status = This->OutputString (This, mSetModeString); TerminalDevice->OutputEscChar = FALSE; if (EFI_ERROR (Status)) { return EFI_DEVICE_ERROR; } This->Mode->Mode = (INT32)ModeNumber; Status = This->ClearScreen (This); if (EFI_ERROR (Status)) { return EFI_DEVICE_ERROR; } return EFI_SUCCESS; } /** 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 TerminalConOutSetAttribute ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN Attribute ) { UINT8 ForegroundControl; UINT8 BackgroundControl; UINT8 BrightControl; INT32 SavedColumn; INT32 SavedRow; EFI_STATUS Status; TERMINAL_DEV *TerminalDevice; SavedColumn = 0; SavedRow = 0; // // get Terminal device data structure pointer. // TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This); // // only the bit0..6 of the Attribute is valid // if ((Attribute | 0x7f) != 0x7f) { return EFI_UNSUPPORTED; } // // Skip outputting the command string for the same attribute // It improves the terminal performance significantly // if (This->Mode->Attribute == (INT32)Attribute) { return EFI_SUCCESS; } // // convert Attribute value to terminal emulator // understandable foreground color // switch (Attribute & 0x07) { case EFI_BLACK: ForegroundControl = 30; break; case EFI_BLUE: ForegroundControl = 34; break; case EFI_GREEN: ForegroundControl = 32; break; case EFI_CYAN: ForegroundControl = 36; break; case EFI_RED: ForegroundControl = 31; break; case EFI_MAGENTA: ForegroundControl = 35; break; case EFI_BROWN: ForegroundControl = 33; break; default: case EFI_LIGHTGRAY: ForegroundControl = 37; break; } // // bit4 of the Attribute indicates bright control // of terminal emulator. // BrightControl = (UINT8)((Attribute >> 3) & 1); // // convert Attribute value to terminal emulator // understandable background color. // switch ((Attribute >> 4) & 0x07) { case EFI_BLACK: BackgroundControl = 40; break; case EFI_BLUE: BackgroundControl = 44; break; case EFI_GREEN: BackgroundControl = 42; break; case EFI_CYAN: BackgroundControl = 46; break; case EFI_RED: BackgroundControl = 41; break; case EFI_MAGENTA: BackgroundControl = 45; break; case EFI_BROWN: BackgroundControl = 43; break; default: case EFI_LIGHTGRAY: BackgroundControl = 47; break; } // // terminal emulator's control sequence to set attributes // mSetAttributeString[BRIGHT_CONTROL_OFFSET] = (CHAR16)('0' + BrightControl); mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 0] = (CHAR16)('0' + (ForegroundControl / 10)); mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 1] = (CHAR16)('0' + (ForegroundControl % 10)); mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 0] = (CHAR16)('0' + (BackgroundControl / 10)); mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 1] = (CHAR16)('0' + (BackgroundControl % 10)); // // save current column and row // for future scrolling back use. // SavedColumn = This->Mode->CursorColumn; SavedRow = This->Mode->CursorRow; TerminalDevice->OutputEscChar = TRUE; Status = This->OutputString (This, mSetAttributeString); TerminalDevice->OutputEscChar = FALSE; if (EFI_ERROR (Status)) { return EFI_DEVICE_ERROR; } // // scroll back to saved cursor position. // This->Mode->CursorColumn = SavedColumn; This->Mode->CursorRow = SavedRow; This->Mode->Attribute = (INT32)Attribute; return EFI_SUCCESS; } /** 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 TerminalConOutClearScreen ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This ) { EFI_STATUS Status; TERMINAL_DEV *TerminalDevice; TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This); // // control sequence for clear screen request // TerminalDevice->OutputEscChar = TRUE; Status = This->OutputString (This, mClearScreenString); TerminalDevice->OutputEscChar = FALSE; if (EFI_ERROR (Status)) { return EFI_DEVICE_ERROR; } Status = This->SetCursorPosition (This, 0, 0); return Status; } /** 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 TerminalConOutSetCursorPosition ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN Column, IN UINTN Row ) { EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode; UINTN MaxColumn; UINTN MaxRow; EFI_STATUS Status; TERMINAL_DEV *TerminalDevice; CHAR16 *String; TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This); // // get current mode // Mode = This->Mode; // // get geometry of current mode // Status = This->QueryMode ( This, Mode->Mode, &MaxColumn, &MaxRow ); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } if ((Column >= MaxColumn) || (Row >= MaxRow)) { return EFI_UNSUPPORTED; } // // control sequence to move the cursor // // Optimize cursor motion control sequences for TtyTerm. Move // within the current line if possible, and don't output anyting if // it isn't necessary. // if ((TerminalDevice->TerminalType == TerminalTypeTtyTerm) && ((UINTN)Mode->CursorRow == Row)) { if ((UINTN)Mode->CursorColumn > Column) { mCursorBackwardString[FW_BACK_OFFSET + 0] = (CHAR16)('0' + ((Mode->CursorColumn - Column) / 10)); mCursorBackwardString[FW_BACK_OFFSET + 1] = (CHAR16)('0' + ((Mode->CursorColumn - Column) % 10)); String = mCursorBackwardString; } else if (Column > (UINTN)Mode->CursorColumn) { mCursorForwardString[FW_BACK_OFFSET + 0] = (CHAR16)('0' + ((Column - Mode->CursorColumn) / 10)); mCursorForwardString[FW_BACK_OFFSET + 1] = (CHAR16)('0' + ((Column - Mode->CursorColumn) % 10)); String = mCursorForwardString; } else { String = L""; // No cursor motion necessary } } else { mSetCursorPositionString[ROW_OFFSET + 0] = (CHAR16)('0' + ((Row + 1) / 10)); mSetCursorPositionString[ROW_OFFSET + 1] = (CHAR16)('0' + ((Row + 1) % 10)); mSetCursorPositionString[COLUMN_OFFSET + 0] = (CHAR16)('0' + ((Column + 1) / 10)); mSetCursorPositionString[COLUMN_OFFSET + 1] = (CHAR16)('0' + ((Column + 1) % 10)); String = mSetCursorPositionString; } TerminalDevice->OutputEscChar = TRUE; Status = This->OutputString (This, String); TerminalDevice->OutputEscChar = FALSE; if (EFI_ERROR (Status)) { return EFI_DEVICE_ERROR; } // // update current cursor position // in the Mode data structure. // Mode->CursorColumn = (INT32)Column; Mode->CursorRow = (INT32)Row; return EFI_SUCCESS; } /** 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 TerminalConOutEnableCursor ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN BOOLEAN Visible ) { if (!Visible) { return EFI_UNSUPPORTED; } return EFI_SUCCESS; } /** 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. @retval TRUE If Graphic is a supported Unicode Box Drawing character. **/ BOOLEAN TerminalIsValidTextGraphics ( IN CHAR16 Graphic, OUT CHAR8 *PcAnsi OPTIONAL, OUT CHAR8 *Ascii 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 = UnicodeToPcAnsiOrAscii; Table->Unicode != 0x0000; Table++) { if (Graphic == Table->Unicode) { if (PcAnsi != NULL) { *PcAnsi = Table->PcAnsi; } if (Ascii != NULL) { *Ascii = Table->Ascii; } return TRUE; } } return FALSE; } /** Detects if a valid ASCII char. @param Ascii An ASCII character. @retval TRUE If it is a valid ASCII character. @retval FALSE If it is not a valid ASCII character. **/ BOOLEAN TerminalIsValidAscii ( IN CHAR16 Ascii ) { // // valid ascii code lies in the extent of 0x20 ~ 0x7f // if ((Ascii >= 0x20) && (Ascii <= 0x7f)) { return TRUE; } return FALSE; } /** Detects if a valid EFI control character. @param CharC An input EFI Control character. @retval TRUE If it is a valid EFI control character. @retval FALSE If it is not a valid EFI control character. **/ 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; }