2 Implementation for EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL protocol.
4 Copyright (c) 2006 - 2008, Intel Corporation. <BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 // This list is used to define the valid extend chars.
19 // It also provides a mapping from Unicode to PCANSI or
20 // ASCII. The ASCII mapping we just made up.
23 STATIC UNICODE_TO_CHAR UnicodeToPcAnsiOrAscii
[] = {
24 { BOXDRAW_HORIZONTAL
, 0xc4, L
'-' },
25 { BOXDRAW_VERTICAL
, 0xb3, L
'|' },
26 { BOXDRAW_DOWN_RIGHT
, 0xda, L
'/' },
27 { BOXDRAW_DOWN_LEFT
, 0xbf, L
'\\' },
28 { BOXDRAW_UP_RIGHT
, 0xc0, L
'\\' },
29 { BOXDRAW_UP_LEFT
, 0xd9, L
'/' },
30 { BOXDRAW_VERTICAL_RIGHT
, 0xc3, L
'|' },
31 { BOXDRAW_VERTICAL_LEFT
, 0xb4, L
'|' },
32 { BOXDRAW_DOWN_HORIZONTAL
, 0xc2, L
'+' },
33 { BOXDRAW_UP_HORIZONTAL
, 0xc1, L
'+' },
34 { BOXDRAW_VERTICAL_HORIZONTAL
, 0xc5, L
'+' },
35 { BOXDRAW_DOUBLE_HORIZONTAL
, 0xcd, L
'-' },
36 { BOXDRAW_DOUBLE_VERTICAL
, 0xba, L
'|' },
37 { BOXDRAW_DOWN_RIGHT_DOUBLE
, 0xd5, L
'/' },
38 { BOXDRAW_DOWN_DOUBLE_RIGHT
, 0xd6, L
'/' },
39 { BOXDRAW_DOUBLE_DOWN_RIGHT
, 0xc9, L
'/' },
40 { BOXDRAW_DOWN_LEFT_DOUBLE
, 0xb8, L
'\\' },
41 { BOXDRAW_DOWN_DOUBLE_LEFT
, 0xb7, L
'\\' },
42 { BOXDRAW_DOUBLE_DOWN_LEFT
, 0xbb, L
'\\' },
43 { BOXDRAW_UP_RIGHT_DOUBLE
, 0xd4, L
'\\' },
44 { BOXDRAW_UP_DOUBLE_RIGHT
, 0xd3, L
'\\' },
45 { BOXDRAW_DOUBLE_UP_RIGHT
, 0xc8, L
'\\' },
46 { BOXDRAW_UP_LEFT_DOUBLE
, 0xbe, L
'/' },
47 { BOXDRAW_UP_DOUBLE_LEFT
, 0xbd, L
'/' },
48 { BOXDRAW_DOUBLE_UP_LEFT
, 0xbc, L
'/' },
49 { BOXDRAW_VERTICAL_RIGHT_DOUBLE
, 0xc6, L
'|' },
50 { BOXDRAW_VERTICAL_DOUBLE_RIGHT
, 0xc7, L
'|' },
51 { BOXDRAW_DOUBLE_VERTICAL_RIGHT
, 0xcc, L
'|' },
52 { BOXDRAW_VERTICAL_LEFT_DOUBLE
, 0xb5, L
'|' },
53 { BOXDRAW_VERTICAL_DOUBLE_LEFT
, 0xb6, L
'|' },
54 { BOXDRAW_DOUBLE_VERTICAL_LEFT
, 0xb9, L
'|' },
55 { BOXDRAW_DOWN_HORIZONTAL_DOUBLE
, 0xd1, L
'+' },
56 { BOXDRAW_DOWN_DOUBLE_HORIZONTAL
, 0xd2, L
'+' },
57 { BOXDRAW_DOUBLE_DOWN_HORIZONTAL
, 0xcb, L
'+' },
58 { BOXDRAW_UP_HORIZONTAL_DOUBLE
, 0xcf, L
'+' },
59 { BOXDRAW_UP_DOUBLE_HORIZONTAL
, 0xd0, L
'+' },
60 { BOXDRAW_DOUBLE_UP_HORIZONTAL
, 0xca, L
'+' },
61 { BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE
, 0xd8, L
'+' },
62 { BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL
, 0xd7, L
'+' },
63 { BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL
, 0xce, L
'+' },
65 { BLOCKELEMENT_FULL_BLOCK
, 0xdb, L
'*' },
66 { BLOCKELEMENT_LIGHT_SHADE
, 0xb0, L
'+' },
68 { GEOMETRICSHAPE_UP_TRIANGLE
, 0x1e, L
'^' },
69 { GEOMETRICSHAPE_RIGHT_TRIANGLE
, 0x10, L
'>' },
70 { GEOMETRICSHAPE_DOWN_TRIANGLE
, 0x1f, L
'v' },
71 { GEOMETRICSHAPE_LEFT_TRIANGLE
, 0x11, L
'<' },
73 { ARROW_LEFT
, 0x3c, L
'<' },
74 { ARROW_UP
, 0x18, L
'^' },
75 { ARROW_RIGHT
, 0x3e, L
'>' },
76 { ARROW_DOWN
, 0x19, L
'v' },
78 { 0x0000, 0x00, L
'\0' }
81 CHAR16 mSetModeString
[] = { ESC
, '[', '=', '3', 'h', 0 };
82 CHAR16 mSetAttributeString
[] = { ESC
, '[', '0', 'm', ESC
, '[', '4', '0', 'm', ESC
, '[', '4', '0', 'm', 0 };
83 CHAR16 mClearScreenString
[] = { ESC
, '[', '2', 'J', 0 };
84 CHAR16 mSetCursorPositionString
[] = { ESC
, '[', '0', '0', ';', '0', '0', 'H', 0 };
87 // Body of the ConOut functions
91 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.Reset().
92 If ExtendeVerification is TRUE, then perform dependent serial device reset,
93 and set display mode to mode 0.
94 If ExtendedVerification is FALSE, only set display mode to mode 0.
96 @param This Indicates the calling context.
97 @param ExtendedVerification Indicates that the driver may perform a more
98 exhaustive verification operation of the device
102 @return The reset operation succeeds.
103 @return EFI_DEVICE_ERROR
104 @return The terminal is not functioning correctly or the serial port reset fails.
109 TerminalConOutReset (
110 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
111 IN BOOLEAN ExtendedVerification
115 TERMINAL_DEV
*TerminalDevice
;
117 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (This
);
120 // Perform a more exhaustive reset by resetting the serial port.
122 if (ExtendedVerification
) {
124 // Report progress code here
126 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
128 PcdGet32 (PcdStatusCodeValueRemoteConsoleReset
),
129 TerminalDevice
->DevicePath
132 Status
= TerminalDevice
->SerialIo
->Reset (TerminalDevice
->SerialIo
);
133 if (EFI_ERROR (Status
)) {
135 // Report error code here
137 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
138 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
139 PcdGet32 (PcdStatusCodeValueRemoteConsoleError
),
140 TerminalDevice
->DevicePath
147 This
->SetAttribute (This
, EFI_TEXT_ATTR (This
->Mode
->Attribute
& 0x0F, EFI_BLACK
));
149 Status
= This
->SetMode (This
, 0);
156 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString().
157 The Unicode string will be converted to terminal expressible data stream
158 and send to terminal via serial port.
160 @param This Indicates the calling context.
161 @param WString The Null-terminated Unicode string to be displayed
162 on the terminal screen.
164 @return EFI_SUCCESS The string is output successfully.
165 @return EFI_DEVICE_ERROR The serial port fails to send the string out.
166 @return EFI_WARN_UNKNOWN_GLYPH Indicates that some of the characters in the Unicode string could not
167 be rendered and are skipped.
168 @return EFI_UNSUPPORTED
173 TerminalConOutOutputString (
174 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
178 TERMINAL_DEV
*TerminalDevice
;
179 EFI_SIMPLE_TEXT_OUTPUT_MODE
*Mode
;
189 // flag used to indicate whether condition happens which will cause
190 // return EFI_WARN_UNKNOWN_GLYPH
198 // get Terminal device data structure pointer.
200 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (This
);
203 // Get current display mode
207 if (Mode
->Mode
> 2) {
208 return EFI_UNSUPPORTED
;
218 for (; *WString
!= CHAR_NULL
; WString
++) {
220 switch (TerminalDevice
->TerminalType
) {
226 if (!TerminalIsValidTextGraphics (*WString
, &GraphicChar
, &AsciiChar
)) {
228 // If it's not a graphic character convert Unicode to ASCII.
230 GraphicChar
= (CHAR8
) *WString
;
232 if (!(TerminalIsValidAscii (GraphicChar
) || TerminalIsValidEfiCntlChar (GraphicChar
))) {
234 // when this driver use the OutputString to output control string,
235 // TerminalDevice->OutputEscChar is set to let the Esc char
236 // to be output to the terminal emulation software.
238 if ((GraphicChar
== 27) && TerminalDevice
->OutputEscChar
) {
246 AsciiChar
= GraphicChar
;
250 if (TerminalDevice
->TerminalType
!= PCANSITYPE
) {
251 GraphicChar
= AsciiChar
;
256 Status
= TerminalDevice
->SerialIo
->Write (
257 TerminalDevice
->SerialIo
,
262 if (EFI_ERROR (Status
)) {
269 UnicodeToUtf8 (*WString
, &Utf8Char
, &ValidBytes
);
271 Status
= TerminalDevice
->SerialIo
->Write (
272 TerminalDevice
->SerialIo
,
276 if (EFI_ERROR (Status
)) {
282 // Update cursor position.
287 if (Mode
->CursorColumn
> 0) {
288 Mode
->CursorColumn
--;
293 if (Mode
->CursorRow
< (INT32
) (MaxRow
- 1)) {
298 case CHAR_CARRIAGE_RETURN
:
299 Mode
->CursorColumn
= 0;
303 if (Mode
->CursorColumn
< (INT32
) (MaxColumn
- 1)) {
305 Mode
->CursorColumn
++;
309 Mode
->CursorColumn
= 0;
310 if (Mode
->CursorRow
< (INT32
) (MaxRow
- 1)) {
322 return EFI_WARN_UNKNOWN_GLYPH
;
328 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
329 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
330 PcdGet32 (PcdStatusCodeValueRemoteConsoleOutputError
),
331 TerminalDevice
->DevicePath
334 return EFI_DEVICE_ERROR
;
339 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.TestString().
340 If one of the characters in the *Wstring is
341 neither valid Unicode drawing characters,
342 not ASCII code, then this function will return
345 @param This Indicates the calling context.
346 @param WString The Null-terminated Unicode string to be tested.
348 @return EFI_SUCCESS The terminal is capable of rendering the output string.
349 @return EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be rendered.
354 TerminalConOutTestString (
355 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
359 TERMINAL_DEV
*TerminalDevice
;
363 // get Terminal device data structure pointer.
365 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (This
);
367 switch (TerminalDevice
->TerminalType
) {
372 Status
= AnsiTestString (TerminalDevice
, WString
);
376 Status
= VTUTF8TestString (TerminalDevice
, WString
);
380 Status
= EFI_UNSUPPORTED
;
389 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.QueryMode().
390 It returns information for an available text mode
391 that the terminal supports.
392 In this driver, we support text mode 80x25 (mode 0),
393 80x50 (mode 1), 100x31 (mode 2).
395 @param This Indicates the calling context.
396 @param ModeNumber The mode number to return information on.
397 @param Columns The returned columns of the requested mode.
398 @param Rows The returned rows of the requested mode.
400 @return EFI_SUCCESS The requested mode information is returned.
401 @return EFI_UNSUPPORTED The mode number is not valid.
402 @return EFI_DEVICE_ERROR
407 TerminalConOutQueryMode (
408 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
414 if (This
->Mode
->MaxMode
> 3) {
415 return EFI_DEVICE_ERROR
;
418 if (ModeNumber
== 0) {
419 *Columns
= MODE0_COLUMN_COUNT
;
420 *Rows
= MODE0_ROW_COUNT
;
422 } else if (ModeNumber
== 1) {
423 *Columns
= MODE1_COLUMN_COUNT
;
424 *Rows
= MODE1_ROW_COUNT
;
426 } else if (ModeNumber
== 2) {
427 *Columns
= MODE2_COLUMN_COUNT
;
428 *Rows
= MODE2_ROW_COUNT
;
432 return EFI_UNSUPPORTED
;
437 Implements EFI_SIMPLE_TEXT_OUT.SetMode().
438 Set the terminal to a specified display mode.
439 In this driver, we only support mode 0.
441 @param This Indicates the calling context.
442 @param ModeNumber The text mode to set.
444 @return EFI_SUCCESS The requested text mode is set.
445 @return EFI_DEVICE_ERROR The requested text mode cannot be set
446 because of serial device error.
447 @return EFI_UNSUPPORTED The text mode number is not valid.
452 TerminalConOutSetMode (
453 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
458 TERMINAL_DEV
*TerminalDevice
;
461 // get Terminal device data structure pointer.
463 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (This
);
465 if (ModeNumber
> 2) {
466 return EFI_UNSUPPORTED
;
470 // Set the current mode
472 This
->Mode
->Mode
= (INT32
) ModeNumber
;
474 This
->ClearScreen (This
);
476 TerminalDevice
->OutputEscChar
= TRUE
;
477 Status
= This
->OutputString (This
, mSetModeString
);
478 TerminalDevice
->OutputEscChar
= FALSE
;
480 if (EFI_ERROR (Status
)) {
481 return EFI_DEVICE_ERROR
;
484 This
->Mode
->Mode
= (INT32
) ModeNumber
;
486 Status
= This
->ClearScreen (This
);
487 if (EFI_ERROR (Status
)) {
488 return EFI_DEVICE_ERROR
;
497 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetAttribute().
499 @param This Indicates the calling context.
500 @param Attribute The attribute to set. Only bit0..6 are valid, all other bits
501 are undefined and must be zero.
503 @return EFI_SUCCESS The requested attribute is set.
504 @return EFI_DEVICE_ERROR The requested attribute cannot be set due to serial port error.
505 @return EFI_UNSUPPORTED The attribute requested is not defined by EFI spec.
510 TerminalConOutSetAttribute (
511 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
515 UINT8 ForegroundControl
;
516 UINT8 BackgroundControl
;
521 TERMINAL_DEV
*TerminalDevice
;
527 // get Terminal device data structure pointer.
529 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (This
);
532 // only the bit0..6 of the Attribute is valid
534 if ((Attribute
| 0x7f) != 0x7f) {
535 return EFI_UNSUPPORTED
;
539 // Skip outputting the command string for the same attribute
540 // It improves the terminal performance siginificantly
542 if (This
->Mode
->Attribute
== (INT32
) Attribute
) {
547 // convert Attribute value to terminal emulator
548 // understandable foreground color
550 switch (Attribute
& 0x07) {
553 ForegroundControl
= 30;
557 ForegroundControl
= 34;
561 ForegroundControl
= 32;
565 ForegroundControl
= 36;
569 ForegroundControl
= 31;
573 ForegroundControl
= 35;
577 ForegroundControl
= 33;
583 ForegroundControl
= 37;
588 // bit4 of the Attribute indicates bright control
589 // of terminal emulator.
591 BrightControl
= (UINT8
) ((Attribute
>> 3) & 1);
594 // convert Attribute value to terminal emulator
595 // understandable background color.
597 switch ((Attribute
>> 4) & 0x07) {
600 BackgroundControl
= 40;
604 BackgroundControl
= 44;
608 BackgroundControl
= 42;
612 BackgroundControl
= 46;
616 BackgroundControl
= 41;
620 BackgroundControl
= 45;
624 BackgroundControl
= 43;
630 BackgroundControl
= 47;
634 // terminal emulator's control sequence to set attributes
636 mSetAttributeString
[BRIGHT_CONTROL_OFFSET
] = (CHAR16
) ('0' + BrightControl
);
637 mSetAttributeString
[FOREGROUND_CONTROL_OFFSET
+ 0] = (CHAR16
) ('0' + (ForegroundControl
/ 10));
638 mSetAttributeString
[FOREGROUND_CONTROL_OFFSET
+ 1] = (CHAR16
) ('0' + (ForegroundControl
% 10));
639 mSetAttributeString
[BACKGROUND_CONTROL_OFFSET
+ 0] = (CHAR16
) ('0' + (BackgroundControl
/ 10));
640 mSetAttributeString
[BACKGROUND_CONTROL_OFFSET
+ 1] = (CHAR16
) ('0' + (BackgroundControl
% 10));
643 // save current column and row
644 // for future scrolling back use.
646 SavedColumn
= This
->Mode
->CursorColumn
;
647 SavedRow
= This
->Mode
->CursorRow
;
649 TerminalDevice
->OutputEscChar
= TRUE
;
650 Status
= This
->OutputString (This
, mSetAttributeString
);
651 TerminalDevice
->OutputEscChar
= FALSE
;
653 if (EFI_ERROR (Status
)) {
654 return EFI_DEVICE_ERROR
;
657 // scroll back to saved cursor position.
659 This
->Mode
->CursorColumn
= SavedColumn
;
660 This
->Mode
->CursorRow
= SavedRow
;
662 This
->Mode
->Attribute
= (INT32
) Attribute
;
670 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.ClearScreen().
671 It clears the ANSI terminal's display to the
672 currently selected background color.
674 @param This Indicates the calling context.
676 @return EFI_SUCCESS The operation completed successfully.
677 @return EFI_DEVICE_ERROR The terminal screen cannot be cleared due to serial port error.
678 @return EFI_UNSUPPORTED The terminal is not in a valid display mode.
683 TerminalConOutClearScreen (
684 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
688 TERMINAL_DEV
*TerminalDevice
;
690 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (This
);
693 // control sequence for clear screen request
695 TerminalDevice
->OutputEscChar
= TRUE
;
696 Status
= This
->OutputString (This
, mClearScreenString
);
697 TerminalDevice
->OutputEscChar
= FALSE
;
699 if (EFI_ERROR (Status
)) {
700 return EFI_DEVICE_ERROR
;
703 Status
= This
->SetCursorPosition (This
, 0, 0);
710 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetCursorPosition().
712 @param This Indicates the calling context.
713 @param Column The row to set cursor to.
714 @param Row The column to set cursor to.
716 @return EFI_SUCCESS The operation completed successfully.
717 @return EFI_DEVICE_ERROR The request fails due to serial port error.
718 @return EFI_UNSUPPORTED The terminal is not in a valid text mode, or the cursor position
719 is invalid for current mode.
724 TerminalConOutSetCursorPosition (
725 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
730 EFI_SIMPLE_TEXT_OUTPUT_MODE
*Mode
;
734 TERMINAL_DEV
*TerminalDevice
;
736 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (This
);
744 // get geometry of current mode
746 Status
= This
->QueryMode (
752 if (EFI_ERROR (Status
)) {
753 return EFI_UNSUPPORTED
;
756 if (Column
>= MaxColumn
|| Row
>= MaxRow
) {
757 return EFI_UNSUPPORTED
;
760 // control sequence to move the cursor
762 mSetCursorPositionString
[ROW_OFFSET
+ 0] = (CHAR16
) ('0' + ((Row
+ 1) / 10));
763 mSetCursorPositionString
[ROW_OFFSET
+ 1] = (CHAR16
) ('0' + ((Row
+ 1) % 10));
764 mSetCursorPositionString
[COLUMN_OFFSET
+ 0] = (CHAR16
) ('0' + ((Column
+ 1) / 10));
765 mSetCursorPositionString
[COLUMN_OFFSET
+ 1] = (CHAR16
) ('0' + ((Column
+ 1) % 10));
767 TerminalDevice
->OutputEscChar
= TRUE
;
768 Status
= This
->OutputString (This
, mSetCursorPositionString
);
769 TerminalDevice
->OutputEscChar
= FALSE
;
771 if (EFI_ERROR (Status
)) {
772 return EFI_DEVICE_ERROR
;
775 // update current cursor position
776 // in the Mode data structure.
778 Mode
->CursorColumn
= (INT32
) Column
;
779 Mode
->CursorRow
= (INT32
) Row
;
786 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
787 In this driver, the cursor cannot be hidden.
789 @param This Indicates the calling context.
790 @param Visible If TRUE, the cursor is set to be visible,
791 If FALSE, the cursor is set to be invisible.
793 @return EFI_SUCCESS The request is valid.
794 @return EFI_UNSUPPORTED The terminal does not support cursor hidden.
799 TerminalConOutEnableCursor (
800 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
805 return EFI_UNSUPPORTED
;
813 Detects if a Unicode char is for Box Drawing text graphics.
815 @param Graphic Unicode char to test.
816 @param PcAnsi Optional pointer to return PCANSI equivalent of
818 @param Ascii Optional pointer to return ASCII equivalent of
821 @return TRUE If Graphic is a supported Unicode Box Drawing character.
825 TerminalIsValidTextGraphics (
827 OUT CHAR8
*PcAnsi
, OPTIONAL
828 OUT CHAR8
*Ascii OPTIONAL
831 UNICODE_TO_CHAR
*Table
;
833 if ((((Graphic
& 0xff00) != 0x2500) && ((Graphic
& 0xff00) != 0x2100))) {
835 // Unicode drawing code charts are all in the 0x25xx range,
841 for (Table
= UnicodeToPcAnsiOrAscii
; Table
->Unicode
!= 0x0000; Table
++) {
842 if (Graphic
== Table
->Unicode
) {
843 if (PcAnsi
!= NULL
) {
844 *PcAnsi
= Table
->PcAnsi
;
848 *Ascii
= Table
->Ascii
;
859 TerminalIsValidAscii (
864 // valid ascii code lies in the extent of 0x20 ~ 0x7f
866 if ((Ascii
>= 0x20) && (Ascii
<= 0x7f)) {
874 TerminalIsValidEfiCntlChar (
879 // only support four control characters.
881 if (CharC
== CHAR_NULL
||
882 CharC
== CHAR_BACKSPACE
||
883 CharC
== CHAR_LINEFEED
||
884 CharC
== CHAR_CARRIAGE_RETURN
||