]>
git.proxmox.com Git - mirror_edk2.git/blob - StdLib/LibC/Uefi/InteractiveIO/IIOwrite.c
2 Write to an Interactive I/O Output device.
4 The functions assume that isatty() is TRUE at the time they are called.
5 Since the UEFI console is a WIDE character device, these functions do all
6 processing using wide characters.
8 It is the responsibility of the caller, or higher level function, to perform
9 any necessary translation between wide and narrow characters.
11 Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
12 This program and the accompanying materials are licensed and made available
13 under the terms and conditions of the BSD License which accompanies this
14 distribution. The full text of the license may be found at
15 http://opensource.org/licenses/bsd-license.php.
17 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
18 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
22 #include <LibConfig.h>
26 #include <sys/termios.h>
27 #include <Device/IIO.h>
29 static wchar_t Spaces
[] = L
" "; // Spaces for expanding TABs
31 #define MAX_TAB_WIDTH ((int)(sizeof(Spaces) / sizeof(wchar_t)) - 1)
33 #define MAX_EXPANSION 3
35 /** Process and buffer one character for output.
37 @param[in] filp Pointer to a file descriptor structure.
38 @param[out] OBuf Pointer to the Output Buffer FIFO.
39 @param[in] InCh The wide character to process.
41 @retval <0 An error occurred. Reason is in errno.
42 * EINVAL The pointer to the IIO object is NULL.
43 * ENOSPC The OBuf FIFO is full.
45 @retval 0 A character was input but not placed in the output buffer.
47 @retval >0 The number of characters buffered. Normally 1, or 2.
48 If a character is discarded because of flag settings, a
52 IIO_WriteOne(struct __filedes
*filp
, cFIFO
*OBuf
, wchar_t InCh
)
55 struct termios
*Termio
;
58 wchar_t wc
[MAX_EXPANSION
]; // Sub-buffer for conversions
59 wchar_t *wcb
; // Pointer to either wc or spaces
60 int numW
= 0; // Wide characters placed in OBuf
61 INT32 TabWidth
; // Each TAB expands into this number of spaces
62 UINT32 CurColumn
; // Current cursor column on the screen
63 UINT32 CurRow
; // Current cursor row on the screen
64 UINT32 PrevColumn
; // Previous column. Used to detect wrapping.
65 UINT32 AdjColumn
; // Current cursor column on the screen
70 if((This
!= NULL
) && (OBuf
->FreeSpace(OBuf
, AsElements
) >= MAX_EXPANSION
)) {
71 Termio
= &This
->Termio
;
72 OFlag
= Termio
->c_oflag
;
73 TabWidth
= (INT32
)This
->Termio
.c_cc
[VTABLEN
];
74 if(TabWidth
> MAX_TAB_WIDTH
) {
75 TabWidth
= MAX_TAB_WIDTH
;
77 CurColumn
= This
->CurrentXY
.Column
;
78 CurRow
= This
->CurrentXY
.Row
;
80 numW
= 1; // The majority of characters buffer one character
83 /* Perform output processing */
90 SpaceIndex
= CurColumn
% TabWidth
; // Number of spaces after a Tab Stop
91 numW
= TabWidth
- SpaceIndex
; // Number of spaces to the next Tab Stop
92 SpaceIndex
= MAX_TAB_WIDTH
- numW
; // Index into the Spaces array
93 wcb
= &Spaces
[SpaceIndex
]; // Point to the appropriate number of spaces
101 wc
[0] = InCh
; // Send the TAB itself - assumes that it does not move cursor.
105 case CHAR_CARRIAGE_RETURN
: //{{
106 if((OFlag
& OCRNL
) == 0) {
107 if((OFlag
& ONLRET
) == 0) {
108 numW
= 0; /* Discard the CR */
109 // Cursor doesn't move
112 wc
[0] = CHAR_CARRIAGE_RETURN
;
118 InCh
= CHAR_LINEFEED
;
120 // Fall through to the NL case
121 case CHAR_LINEFEED
: //{{
123 wc
[0] = CHAR_CARRIAGE_RETURN
;
124 wc
[1] = CHAR_LINEFEED
;
130 case CHAR_BACKSPACE
: //{{
132 wc
[0] = CHAR_BACKSPACE
;
133 CurColumn
= (UINT32
)ModuloDecrement(CurColumn
, (UINT32
)This
->MaxColumn
);
136 numW
= 0; // Discard the backspace if in column 0
142 numW
= 0; // Discard the EOT character
143 // Cursor doesn't move
146 // Fall through to default in order to potentially output "^D"
148 if((InCh
>= 0) && (InCh
< L
' ')) {
149 // InCh contains a control character
157 numW
= 0; // Discard. Not a UEFI supported control character.
161 // Regular printing character
167 if(numW
< MAX_EXPANSION
) {
168 wc
[numW
] = 0; // Terminate the sub-buffer
171 // Adjust the cursor position
172 PrevColumn
= CurColumn
;
173 CurColumn
= ModuloAdd(PrevColumn
, AdjColumn
, (UINT32
)This
->MaxColumn
);
174 if(CurColumn
< PrevColumn
) {
175 // We must have wrapped, so we are on the next Row
177 if(CurRow
>= This
->MaxRow
) {
178 // The screen has scrolled so need to adjust Initial location.
179 --This
->InitialXY
.Row
; // Initial row has moved up one
180 CurRow
= (UINT32
)(This
->MaxRow
- 1); // We stay on the bottom row
184 This
->CurrentXY
.Column
= CurColumn
;
185 This
->CurrentXY
.Row
= CurRow
;
188 // Output processing disabled -- RAW output mode
192 // Put the character(s) into the output buffer
194 (void)OBuf
->Write(OBuf
, (const void *)wcb
, (size_t)numW
);