[CONUTILS] Split stream.c into input and output stream modules.
[reactos.git] / sdk / lib / conutils / screen.c
1 /*
2 * PROJECT: ReactOS Console Utilities Library
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Console/terminal screen management.
5 * COPYRIGHT: Copyright 2017-2018 ReactOS Team
6 * Copyright 2017-2018 Hermes Belusca-Maito
7 */
8
9 /* FIXME: Temporary HACK before we cleanly support UNICODE functions */
10 #define UNICODE
11 #define _UNICODE
12
13 #include <windef.h>
14 #include <winbase.h>
15 // #include <winnls.h>
16 #include <wincon.h> // Console APIs (only if kernel32 support included)
17 #include <strsafe.h>
18
19 #include "conutils.h"
20 #include "stream.h"
21 #include "screen.h"
22
23 // Temporary HACK
24 #define CON_STREAM_WRITE ConStreamWrite
25
26
27 #if 0
28
29 VOID
30 ConClearLine(IN PCON_STREAM Stream)
31 {
32 HANDLE hOutput = ConStreamGetOSHandle(Stream);
33
34 /*
35 * Erase the full line where the cursor is, and move
36 * the cursor back to the beginning of the line.
37 */
38
39 if (IsConsoleHandle(hOutput))
40 {
41 CONSOLE_SCREEN_BUFFER_INFO csbi;
42 DWORD dwWritten;
43
44 GetConsoleScreenBufferInfo(hOutput, &csbi);
45
46 csbi.dwCursorPosition.X = 0;
47 // csbi.dwCursorPosition.Y;
48
49 FillConsoleOutputCharacterW(hOutput, L' ',
50 csbi.dwSize.X,
51 csbi.dwCursorPosition,
52 &dwWritten);
53 SetConsoleCursorPosition(hOutput, csbi.dwCursorPosition);
54 }
55 else if (IsTTYHandle(hOutput))
56 {
57 ConPuts(Stream, L"\x1B[2K\x1B[1G"); // FIXME: Just use WriteFile
58 }
59 // else, do nothing for files
60 }
61
62 #endif
63
64
65 BOOL
66 ConGetScreenInfo(
67 IN PCON_SCREEN Screen,
68 OUT PCONSOLE_SCREEN_BUFFER_INFO pcsbi)
69 {
70 BOOL Success;
71 HANDLE hOutput;
72
73 /* Parameters validation */
74 if (!Screen || !pcsbi)
75 return FALSE;
76
77 hOutput = ConStreamGetOSHandle(Screen->Stream);
78
79 /* Screen handle must be of TTY type (console or TTY) */
80 if (!IsTTYHandle(hOutput))
81 return FALSE;
82
83 /* Update cached screen information */
84 if (IsConsoleHandle(hOutput))
85 {
86 Success = GetConsoleScreenBufferInfo(hOutput, &Screen->csbi);
87 }
88 else
89 {
90 #if 0
91 /* TODO: Do something adequate for TTYs */
92 // FIXME: At the moment we return hardcoded info.
93 Screen->csbi.dwSize.X = 80;
94 Screen->csbi.dwSize.Y = 25;
95
96 // Screen->csbi.dwCursorPosition;
97 // Screen->csbi.wAttributes;
98 // Screen->csbi.srWindow;
99 Screen->csbi.dwMaximumWindowSize = Screen->csbi.dwSize;
100 #else
101 hOutput = CreateFileW(L"CONOUT$", GENERIC_READ|GENERIC_WRITE,
102 FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
103 OPEN_EXISTING, 0, NULL);
104
105 Success = IsConsoleHandle(hOutput) &&
106 GetConsoleScreenBufferInfo(hOutput, &Screen->csbi);
107
108 CloseHandle(hOutput);
109 #endif
110 }
111
112 if (Success)
113 {
114 /* Return it to the caller */
115 *pcsbi = Screen->csbi;
116 }
117
118 return Success;
119 }
120
121 // For real consoles, erase everything, otherwise (TTY) erase just the "screen".
122 // FIXME: Or we can add a BOOL flag?
123 VOID
124 ConClearScreen(IN PCON_SCREEN Screen)
125 {
126 HANDLE hOutput;
127
128 /* Parameters validation */
129 if (!Screen) return;
130
131 #if 0
132 /* Get the size of the visual screen */
133 if (!ConGetScreenInfo(Screen, &csbi))
134 {
135 /* We assume it's a file handle */
136 return;
137 }
138 #endif
139
140 hOutput = ConStreamGetOSHandle(Screen->Stream);
141
142 if (IsConsoleHandle(hOutput))
143 {
144 CONSOLE_SCREEN_BUFFER_INFO csbi;
145 COORD coPos;
146 DWORD dwWritten;
147
148 GetConsoleScreenBufferInfo(hOutput, &csbi);
149
150 coPos.X = 0;
151 coPos.Y = 0;
152 FillConsoleOutputAttribute(hOutput, csbi.wAttributes,
153 csbi.dwSize.X * csbi.dwSize.Y,
154 coPos, &dwWritten);
155 FillConsoleOutputCharacterW(hOutput, L' ',
156 csbi.dwSize.X * csbi.dwSize.Y,
157 coPos, &dwWritten);
158 SetConsoleCursorPosition(hOutput, coPos);
159 }
160 else if (IsTTYHandle(hOutput))
161 {
162 /* Clear the full screen and move the cursor to (0,0) */
163 ConPuts(Screen->Stream, L"\x1B[2J\x1B[1;1H");
164 }
165 else
166 {
167 /* Issue a Form-Feed control */
168 WCHAR ch = L'\f';
169 CON_STREAM_WRITE(Screen->Stream, &ch, 1);
170 }
171 }
172
173 /* EOF */