xref: /reactos/base/shell/cmd/console.c (revision c2c66aff)
1 /*
2  *  CONSOLE.C - console input/output functions.
3  *
4  *
5  *  History:
6  *
7  *    20-Jan-1999 (Eric Kohl)
8  *        started
9  *
10  *    03-Apr-2005 (Magnus Olsen <magnus@greatlord.com>)
11  *        Remove all hardcoded strings in En.rc
12  *
13  *    01-Jul-2005 (Brandon Turner <turnerb7@msu.edu>)
14  *        Added ConPrintfPaging and ConOutPrintfPaging
15  *
16  *    02-Feb-2007 (Paolo Devoti <devotip at gmail.com>)
17  *        Fixed ConPrintfPaging
18  */
19 
20 #include "precomp.h"
21 
22 #define OUTPUT_BUFFER_SIZE  4096
23 
24 /* Cache codepage for text streams */
25 UINT InputCodePage;
26 UINT OutputCodePage;
27 
28 /* Global console Screen and Pager */
29 CON_SCREEN StdOutScreen = INIT_CON_SCREEN(StdOut);
30 CON_PAGER  StdOutPager  = INIT_CON_PAGER(&StdOutScreen);
31 
32 
33 
34 /********************* Console STREAM IN utility functions ********************/
35 
36 VOID ConInDisable(VOID)
37 {
38     HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
39     DWORD dwMode;
40 
41     GetConsoleMode(hInput, &dwMode);
42     dwMode &= ~ENABLE_PROCESSED_INPUT;
43     SetConsoleMode(hInput, dwMode);
44 }
45 
46 VOID ConInEnable(VOID)
47 {
48     HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
49     DWORD dwMode;
50 
51     GetConsoleMode(hInput, &dwMode);
52     dwMode |= ENABLE_PROCESSED_INPUT;
53     SetConsoleMode(hInput, dwMode);
54 }
55 
56 VOID ConInFlush(VOID)
57 {
58     FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
59 }
60 
61 VOID ConInKey(PINPUT_RECORD lpBuffer)
62 {
63     HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
64     DWORD  dwRead;
65 
66     if (hInput == INVALID_HANDLE_VALUE)
67         WARN ("Invalid input handle!!!\n");
68 
69     do
70     {
71         ReadConsoleInput(hInput, lpBuffer, 1, &dwRead);
72         if (lpBuffer->EventType == KEY_EVENT &&
73             lpBuffer->Event.KeyEvent.bKeyDown)
74         {
75             break;
76         }
77     }
78     while (TRUE);
79 }
80 
81 VOID ConInString(LPTSTR lpInput, DWORD dwLength)
82 {
83     DWORD dwOldMode;
84     DWORD dwRead = 0;
85     HANDLE hFile;
86 
87     LPTSTR p;
88     PCHAR pBuf;
89 
90 #ifdef _UNICODE
91     pBuf = (PCHAR)cmd_alloc(dwLength - 1);
92 #else
93     pBuf = lpInput;
94 #endif
95     ZeroMemory(lpInput, dwLength * sizeof(TCHAR));
96     hFile = GetStdHandle(STD_INPUT_HANDLE);
97     GetConsoleMode(hFile, &dwOldMode);
98 
99     SetConsoleMode(hFile, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
100 
101     ReadFile(hFile, (PVOID)pBuf, dwLength - 1, &dwRead, NULL);
102 
103 #ifdef _UNICODE
104     MultiByteToWideChar(InputCodePage, 0, pBuf, dwRead, lpInput, dwLength - 1);
105     cmd_free(pBuf);
106 #endif
107     for (p = lpInput; *p; p++)
108     {
109         if (*p == _T('\x0d'))
110         {
111             *p = _T('\0');
112             break;
113         }
114     }
115 
116     SetConsoleMode(hFile, dwOldMode);
117 }
118 
119 
120 
121 /******************** Console STREAM OUT utility functions ********************/
122 
123 VOID ConOutChar(TCHAR c)
124 {
125     ConWrite(StdOut, &c, 1);
126 }
127 
128 VOID ConErrChar(TCHAR c)
129 {
130     ConWrite(StdErr, &c, 1);
131 }
132 
133 VOID __cdecl ConFormatMessage(PCON_STREAM Stream, DWORD MessageId, ...)
134 {
135     INT Len;
136     va_list arg_ptr;
137 
138     va_start(arg_ptr, MessageId);
139     Len = ConMsgPrintfV(Stream,
140                         FORMAT_MESSAGE_FROM_SYSTEM,
141                         NULL,
142                         MessageId,
143                         LANG_USER_DEFAULT,
144                         arg_ptr);
145     va_end(arg_ptr);
146 
147     if (Len <= 0)
148         ConResPrintf(Stream, STRING_CONSOLE_ERROR, MessageId);
149 }
150 
151 
152 
153 /************************** Console PAGER functions ***************************/
154 
155 BOOL ConPrintfVPaging(PCON_PAGER Pager, BOOL StartPaging, LPTSTR szFormat, va_list arg_ptr)
156 {
157     // INT len;
158     TCHAR szOut[OUTPUT_BUFFER_SIZE];
159 
160     /* Return if no string has been given */
161     if (szFormat == NULL)
162         return TRUE;
163 
164     /*len =*/ _vstprintf(szOut, szFormat, arg_ptr);
165 
166     // return ConPutsPaging(Pager, PagePrompt, StartPaging, szOut);
167     return ConWritePaging(Pager, PagePrompt, StartPaging,
168                           szOut, wcslen(szOut));
169 }
170 
171 BOOL __cdecl ConOutPrintfPaging(BOOL StartPaging, LPTSTR szFormat, ...)
172 {
173     BOOL bRet;
174     va_list arg_ptr;
175 
176     va_start(arg_ptr, szFormat);
177     bRet = ConPrintfVPaging(&StdOutPager, StartPaging, szFormat, arg_ptr);
178     va_end(arg_ptr);
179     return bRet;
180 }
181 
182 VOID ConOutResPaging(BOOL StartPaging, UINT resID)
183 {
184     ConResPaging(&StdOutPager, PagePrompt, StartPaging, resID);
185 }
186 
187 
188 
189 /************************** Console SCREEN functions **************************/
190 
191 VOID SetCursorXY(SHORT x, SHORT y)
192 {
193     COORD coPos;
194 
195     coPos.X = x;
196     coPos.Y = y;
197     SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coPos);
198 }
199 
200 VOID GetCursorXY(PSHORT x, PSHORT y)
201 {
202     CONSOLE_SCREEN_BUFFER_INFO csbi;
203 
204     GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
205 
206     *x = csbi.dwCursorPosition.X;
207     *y = csbi.dwCursorPosition.Y;
208 }
209 
210 SHORT GetCursorX(VOID)
211 {
212     CONSOLE_SCREEN_BUFFER_INFO csbi;
213 
214     GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
215     return csbi.dwCursorPosition.X;
216 }
217 
218 SHORT GetCursorY(VOID)
219 {
220     CONSOLE_SCREEN_BUFFER_INFO csbi;
221 
222     GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
223     return csbi.dwCursorPosition.Y;
224 }
225 
226 VOID SetCursorType(BOOL bInsert, BOOL bVisible)
227 {
228     CONSOLE_CURSOR_INFO cci;
229 
230     cci.dwSize = bInsert ? 10 : 99;
231     cci.bVisible = bVisible;
232 
233     SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
234 }
235 
236 VOID GetScreenSize(PSHORT maxx, PSHORT maxy)
237 {
238     CONSOLE_SCREEN_BUFFER_INFO csbi;
239 
240     if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
241     {
242         csbi.dwSize.X = 80;
243         csbi.dwSize.Y = 25;
244     }
245 
246     if (maxx) *maxx = csbi.dwSize.X;
247     if (maxy) *maxy = csbi.dwSize.Y;
248 }
249 
250 
251 
252 
253 #ifdef INCLUDE_CMD_COLOR
254 
255 BOOL ConGetDefaultAttributes(PWORD pwDefAttr)
256 {
257     BOOL Success;
258     HANDLE hConsole;
259     CONSOLE_SCREEN_BUFFER_INFO csbi;
260 
261     /* Do not modify *pwDefAttr if we fail, in which case use default attributes */
262 
263     hConsole = CreateFile(_T("CONOUT$"), GENERIC_READ|GENERIC_WRITE,
264                           FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
265                           OPEN_EXISTING, 0, NULL);
266     if (hConsole == INVALID_HANDLE_VALUE)
267         return FALSE; // No default console
268 
269     Success = GetConsoleScreenBufferInfo(hConsole, &csbi);
270     if (Success)
271         *pwDefAttr = csbi.wAttributes;
272 
273     CloseHandle(hConsole);
274     return Success;
275 }
276 
277 #endif
278 
279 
280 BOOL ConSetTitle(IN LPCTSTR lpConsoleTitle)
281 {
282     /* Now really set the console title */
283     return SetConsoleTitle(lpConsoleTitle);
284 }
285 
286 #ifdef INCLUDE_CMD_BEEP
287 VOID ConRingBell(HANDLE hOutput)
288 {
289 #if 0
290     /* Emit an error beep sound */
291     if (IsConsoleHandle(hOutput))
292         Beep(800, 200);
293     else if (IsTTYHandle(hOutput))
294         ConOutPuts(_T("\a")); // BEL character 0x07
295     else
296 #endif
297         MessageBeep(-1);
298 }
299 #endif
300 
301 #ifdef INCLUDE_CMD_COLOR
302 BOOL ConSetScreenColor(HANDLE hOutput, WORD wColor, BOOL bFill)
303 {
304     DWORD dwWritten;
305     CONSOLE_SCREEN_BUFFER_INFO csbi;
306     COORD coPos;
307 
308     /* Foreground and Background colors can't be the same */
309     if ((wColor & 0x0F) == (wColor & 0xF0) >> 4)
310         return FALSE;
311 
312     /* Fill the whole background if needed */
313     if (bFill)
314     {
315         GetConsoleScreenBufferInfo(hOutput, &csbi);
316 
317         coPos.X = 0;
318         coPos.Y = 0;
319         FillConsoleOutputAttribute(hOutput,
320                                    wColor & 0x00FF,
321                                    csbi.dwSize.X * csbi.dwSize.Y,
322                                    coPos,
323                                    &dwWritten);
324     }
325 
326     /* Set the text attribute */
327     SetConsoleTextAttribute(hOutput, wColor & 0x00FF);
328     return TRUE;
329 }
330 #endif
331 
332 /* EOF */
333