Reactos
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 */
25UINT InputCodePage;
26UINT OutputCodePage;
27
28/* Global console Screen and Pager */
29CON_SCREEN StdOutScreen = INIT_CON_SCREEN(StdOut);
30CON_PAGER StdOutPager = INIT_CON_PAGER(&StdOutScreen);
31
32
33
34/********************* Console STREAM IN utility functions ********************/
35
36VOID 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
46VOID 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
56VOID ConInFlush(VOID)
57{
58 FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
59}
60
61VOID 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
81VOID ConInString(LPWSTR lpInput, DWORD dwLength)
82{
83 DWORD dwOldMode;
84 DWORD dwRead = 0;
85 HANDLE hFile;
86
87 LPWSTR p;
88 PCHAR pBuf;
89
90 pBuf = (PCHAR)cmd_alloc(dwLength - 1);
91
92 ZeroMemory(lpInput, dwLength * sizeof(WCHAR));
93 hFile = GetStdHandle(STD_INPUT_HANDLE);
94 GetConsoleMode(hFile, &dwOldMode);
95
96 SetConsoleMode(hFile, ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
97
98 ReadFile(hFile, (PVOID)pBuf, dwLength - 1, &dwRead, NULL);
99
100 MultiByteToWideChar(InputCodePage, 0, pBuf, dwRead, lpInput, dwLength - 1);
101 cmd_free(pBuf);
102
103 for (p = lpInput; *p; p++)
104 {
105 if (*p == L'\r') // Terminate at the carriage-return.
106 {
107 *p = L'\0';
108 break;
109 }
110 }
111
112 SetConsoleMode(hFile, dwOldMode);
113}
114
115
116
117/******************** Console STREAM OUT utility functions ********************/
118
119VOID ConOutChar(WCHAR c)
120{
121 ConWrite(StdOut, &c, 1);
122}
123
124VOID ConErrChar(WCHAR c)
125{
126 ConWrite(StdErr, &c, 1);
127}
128
129VOID __cdecl ConFormatMessage(PCON_STREAM Stream, DWORD MessageId, ...)
130{
131 INT Len;
132 va_list arg_ptr;
133
134 va_start(arg_ptr, MessageId);
135 Len = ConMsgPrintfV(Stream,
136 FORMAT_MESSAGE_FROM_SYSTEM,
137 NULL,
138 MessageId,
139 LANG_USER_DEFAULT,
140 &arg_ptr);
141 va_end(arg_ptr);
142
143 if (Len <= 0)
144 ConResPrintf(Stream, STRING_CONSOLE_ERROR, MessageId);
145}
146
147
148
149/************************** Console PAGER functions ***************************/
150
151BOOL ConPrintfVPaging(PCON_PAGER Pager, BOOL StartPaging, LPWSTR szFormat, va_list arg_ptr)
152{
153 // INT len;
154 WCHAR szOut[OUTPUT_BUFFER_SIZE];
155
156 /* Return if no string has been given */
157 if (szFormat == NULL)
158 return TRUE;
159
160 /*len =*/ vswprintf(szOut, szFormat, arg_ptr);
161
162 // return ConPutsPaging(Pager, PagePrompt, StartPaging, szOut);
163 return ConWritePaging(Pager, PagePrompt, StartPaging,
164 szOut, wcslen(szOut));
165}
166
167BOOL __cdecl ConOutPrintfPaging(BOOL StartPaging, LPWSTR szFormat, ...)
168{
169 BOOL bRet;
170 va_list arg_ptr;
171
172 va_start(arg_ptr, szFormat);
173 bRet = ConPrintfVPaging(&StdOutPager, StartPaging, szFormat, arg_ptr);
174 va_end(arg_ptr);
175 return bRet;
176}
177
178VOID ConOutResPaging(BOOL StartPaging, UINT resID)
179{
180 ConResPaging(&StdOutPager, PagePrompt, StartPaging, resID);
181}
182
183
184
185/************************** Console SCREEN functions **************************/
186
187VOID SetCursorXY(SHORT x, SHORT y)
188{
189 COORD coPos;
190
191 coPos.X = x;
192 coPos.Y = y;
193 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coPos);
194}
195
196VOID GetCursorXY(PSHORT x, PSHORT y)
197{
198 CONSOLE_SCREEN_BUFFER_INFO csbi;
199
200 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
201
202 *x = csbi.dwCursorPosition.X;
203 *y = csbi.dwCursorPosition.Y;
204}
205
206SHORT GetCursorX(VOID)
207{
208 CONSOLE_SCREEN_BUFFER_INFO csbi;
209
210 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
211 return csbi.dwCursorPosition.X;
212}
213
214SHORT GetCursorY(VOID)
215{
216 CONSOLE_SCREEN_BUFFER_INFO csbi;
217
218 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
219 return csbi.dwCursorPosition.Y;
220}
221
222VOID SetCursorType(BOOL bInsert, BOOL bVisible)
223{
224 CONSOLE_CURSOR_INFO cci;
225
226 cci.dwSize = bInsert ? 10 : 99;
227 cci.bVisible = bVisible;
228
229 SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
230}
231
232VOID GetScreenSize(PSHORT maxx, PSHORT maxy)
233{
234 CONSOLE_SCREEN_BUFFER_INFO csbi;
235
236 if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
237 {
238 csbi.dwSize.X = 80;
239 csbi.dwSize.Y = 25;
240 }
241
242 if (maxx) *maxx = csbi.dwSize.X;
243 if (maxy) *maxy = csbi.dwSize.Y;
244}
245
246
247
248
249#ifdef INCLUDE_CMD_COLOR
250
251BOOL ConGetDefaultAttributes(PWORD pwDefAttr)
252{
253 BOOL Success;
254 HANDLE hConsole;
255 CONSOLE_SCREEN_BUFFER_INFO csbi;
256
257 /* Do not modify *pwDefAttr if we fail, in which case use default attributes */
258
259 hConsole = CreateFile(_T("CONOUT$"), GENERIC_READ|GENERIC_WRITE,
260 FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
261 OPEN_EXISTING, 0, NULL);
262 if (hConsole == INVALID_HANDLE_VALUE)
263 return FALSE; // No default console
264
265 Success = GetConsoleScreenBufferInfo(hConsole, &csbi);
266 if (Success)
267 *pwDefAttr = csbi.wAttributes;
268
269 CloseHandle(hConsole);
270 return Success;
271}
272
273#endif
274
275
276BOOL ConSetTitle(IN LPCWSTR lpConsoleTitle)
277{
278 /* Now really set the console title */
279 return SetConsoleTitle(lpConsoleTitle);
280}
281
282#ifdef INCLUDE_CMD_BEEP
283VOID ConRingBell(HANDLE hOutput)
284{
285#if 0
286 /* Emit an error beep sound */
287 if (IsConsoleHandle(hOutput))
288 Beep(800, 200);
289 else if (IsTTYHandle(hOutput))
290 ConOutPuts(_T("\a")); // BEL character 0x07
291 else
292#endif
293 MessageBeep(-1);
294}
295#endif
296
297#ifdef INCLUDE_CMD_COLOR
298BOOL ConSetScreenColor(HANDLE hOutput, WORD wColor, BOOL bFill)
299{
300 DWORD dwWritten;
301 CONSOLE_SCREEN_BUFFER_INFO csbi;
302 COORD coPos;
303
304 /* Foreground and Background colors can't be the same */
305 if ((wColor & 0x0F) == (wColor & 0xF0) >> 4)
306 return FALSE;
307
308 /* Fill the whole background if needed */
309 if (bFill)
310 {
311 GetConsoleScreenBufferInfo(hOutput, &csbi);
312
313 coPos.X = 0;
314 coPos.Y = 0;
315 FillConsoleOutputAttribute(hOutput,
316 wColor & 0x00FF,
317 csbi.dwSize.X * csbi.dwSize.Y,
318 coPos,
319 &dwWritten);
320 }
321
322 /* Set the text attribute */
323 SetConsoleTextAttribute(hOutput, wColor & 0x00FF);
324 return TRUE;
325}
326#endif
327
328#include <cjkcode.h>
329#include "wcwidth.c"
330
331// NOTE: The check against 0x80 is to avoid calling the helper function
332// for characters that we already know are not full-width.
333#define IS_FULL_WIDTH(wch) \
334 (((USHORT)(wch) >= 0x0080) && (mk_wcwidth_cjk(wch) == 2))
335
336SIZE_T ConGetTextWidthW(PCWSTR pszText)
337{
338 SIZE_T ich, cxWidth;
339
340 if (!IsCJKCodePage(OutputCodePage))
341 return _tcslen(pszText);
342
343 for (ich = cxWidth = 0; pszText[ich]; ++ich)
344 {
345 if (IS_FULL_WIDTH(pszText[ich]))
346 cxWidth += 2;
347 else
348 ++cxWidth;
349 }
350
351 return cxWidth;
352}
353
354SIZE_T ConGetTextWidthA(PCSTR pszText)
355{
356 int cchMax;
357 PWSTR pszWide;
358 SIZE_T cxWidth;
359
360 cchMax = MultiByteToWideChar(OutputCodePage, 0, pszText, -1, NULL, 0);
361 pszWide = cmd_alloc(cchMax * sizeof(WCHAR));
362 MultiByteToWideChar(OutputCodePage, 0, pszText, -1, pszWide, cchMax);
363 cxWidth = ConGetTextWidthW(pszWide);
364 cmd_free(pszWide);
365 return cxWidth;
366}
367
368/* EOF */