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