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