Reactos
at listview 368 lines 8.4 kB view raw
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 */