Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369/* * CONSOLE.C - console input/output functions. * * * History: * * 20-Jan-1999 (Eric Kohl) * started * * 03-Apr-2005 (Magnus Olsen <magnus@greatlord.com>) * Remove all hardcoded strings in En.rc * * 01-Jul-2005 (Brandon Turner <turnerb7@msu.edu>) * Added ConPrintfPaging and ConOutPrintfPaging * * 02-Feb-2007 (Paolo Devoti <devotip at gmail.com>) * Fixed ConPrintfPaging */
#include "precomp.h"
#define OUTPUT_BUFFER_SIZE 4096
/* Cache codepage for text streams */UINT InputCodePage;UINT OutputCodePage;
/* Global console Screen and Pager */CON_SCREEN StdOutScreen = INIT_CON_SCREEN(StdOut);CON_PAGER StdOutPager = INIT_CON_PAGER(&StdOutScreen);
/********************* Console STREAM IN utility functions ********************/
VOID ConInDisable(VOID){ HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE); DWORD dwMode;
GetConsoleMode(hInput, &dwMode); dwMode &= ~ENABLE_PROCESSED_INPUT; SetConsoleMode(hInput, dwMode);}
VOID ConInEnable(VOID){ HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE); DWORD dwMode;
GetConsoleMode(hInput, &dwMode); dwMode |= ENABLE_PROCESSED_INPUT; SetConsoleMode(hInput, dwMode);}
VOID ConInFlush(VOID){ FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));}
VOID ConInKey(PINPUT_RECORD lpBuffer){ HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE); DWORD dwRead;
if (hInput == INVALID_HANDLE_VALUE) WARN ("Invalid input handle!!!\n");
do { ReadConsoleInput(hInput, lpBuffer, 1, &dwRead); if (lpBuffer->EventType == KEY_EVENT && lpBuffer->Event.KeyEvent.bKeyDown) { break; } } while (TRUE);}
VOID ConInString(LPWSTR lpInput, DWORD dwLength){ DWORD dwOldMode; DWORD dwRead = 0; HANDLE hFile;
LPWSTR p; PCHAR pBuf;
pBuf = (PCHAR)cmd_alloc(dwLength - 1);
ZeroMemory(lpInput, dwLength * sizeof(WCHAR)); hFile = GetStdHandle(STD_INPUT_HANDLE); GetConsoleMode(hFile, &dwOldMode);
SetConsoleMode(hFile, ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
ReadFile(hFile, (PVOID)pBuf, dwLength - 1, &dwRead, NULL);
MultiByteToWideChar(InputCodePage, 0, pBuf, dwRead, lpInput, dwLength - 1); cmd_free(pBuf);
for (p = lpInput; *p; p++) { if (*p == L'\r') // Terminate at the carriage-return. { *p = L'\0'; break; } }
SetConsoleMode(hFile, dwOldMode);}
/******************** Console STREAM OUT utility functions ********************/
VOID ConOutChar(WCHAR c){ ConWrite(StdOut, &c, 1);}
VOID ConErrChar(WCHAR c){ ConWrite(StdErr, &c, 1);}
VOID __cdecl ConFormatMessage(PCON_STREAM Stream, DWORD MessageId, ...){ INT Len; va_list arg_ptr;
va_start(arg_ptr, MessageId); Len = ConMsgPrintfV(Stream, FORMAT_MESSAGE_FROM_SYSTEM, NULL, MessageId, LANG_USER_DEFAULT, &arg_ptr); va_end(arg_ptr);
if (Len <= 0) ConResPrintf(Stream, STRING_CONSOLE_ERROR, MessageId);}
/************************** Console PAGER functions ***************************/
BOOL ConPrintfVPaging(PCON_PAGER Pager, BOOL StartPaging, LPWSTR szFormat, va_list arg_ptr){ // INT len; WCHAR szOut[OUTPUT_BUFFER_SIZE];
/* Return if no string has been given */ if (szFormat == NULL) return TRUE;
/*len =*/ vswprintf(szOut, szFormat, arg_ptr);
// return ConPutsPaging(Pager, PagePrompt, StartPaging, szOut); return ConWritePaging(Pager, PagePrompt, StartPaging, szOut, wcslen(szOut));}
BOOL __cdecl ConOutPrintfPaging(BOOL StartPaging, LPWSTR szFormat, ...){ BOOL bRet; va_list arg_ptr;
va_start(arg_ptr, szFormat); bRet = ConPrintfVPaging(&StdOutPager, StartPaging, szFormat, arg_ptr); va_end(arg_ptr); return bRet;}
VOID ConOutResPaging(BOOL StartPaging, UINT resID){ ConResPaging(&StdOutPager, PagePrompt, StartPaging, resID);}
/************************** Console SCREEN functions **************************/
VOID SetCursorXY(SHORT x, SHORT y){ COORD coPos;
coPos.X = x; coPos.Y = y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coPos);}
VOID GetCursorXY(PSHORT x, PSHORT y){ CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
*x = csbi.dwCursorPosition.X; *y = csbi.dwCursorPosition.Y;}
SHORT GetCursorX(VOID){ CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); return csbi.dwCursorPosition.X;}
SHORT GetCursorY(VOID){ CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); return csbi.dwCursorPosition.Y;}
VOID SetCursorType(BOOL bInsert, BOOL bVisible){ CONSOLE_CURSOR_INFO cci;
cci.dwSize = bInsert ? 10 : 99; cci.bVisible = bVisible;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);}
VOID GetScreenSize(PSHORT maxx, PSHORT maxy){ CONSOLE_SCREEN_BUFFER_INFO csbi;
if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) { csbi.dwSize.X = 80; csbi.dwSize.Y = 25; }
if (maxx) *maxx = csbi.dwSize.X; if (maxy) *maxy = csbi.dwSize.Y;}
#ifdef INCLUDE_CMD_COLOR
BOOL ConGetDefaultAttributes(PWORD pwDefAttr){ BOOL Success; HANDLE hConsole; CONSOLE_SCREEN_BUFFER_INFO csbi;
/* Do not modify *pwDefAttr if we fail, in which case use default attributes */
hConsole = CreateFile(_T("CONOUT$"), GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hConsole == INVALID_HANDLE_VALUE) return FALSE; // No default console
Success = GetConsoleScreenBufferInfo(hConsole, &csbi); if (Success) *pwDefAttr = csbi.wAttributes;
CloseHandle(hConsole); return Success;}
#endif
BOOL ConSetTitle(IN LPCWSTR lpConsoleTitle){ /* Now really set the console title */ return SetConsoleTitle(lpConsoleTitle);}
#ifdef INCLUDE_CMD_BEEPVOID ConRingBell(HANDLE hOutput){#if 0 /* Emit an error beep sound */ if (IsConsoleHandle(hOutput)) Beep(800, 200); else if (IsTTYHandle(hOutput)) ConOutPuts(_T("\a")); // BEL character 0x07 else#endif MessageBeep(-1);}#endif
#ifdef INCLUDE_CMD_COLORBOOL ConSetScreenColor(HANDLE hOutput, WORD wColor, BOOL bFill){ DWORD dwWritten; CONSOLE_SCREEN_BUFFER_INFO csbi; COORD coPos;
/* Foreground and Background colors can't be the same */ if ((wColor & 0x0F) == (wColor & 0xF0) >> 4) return FALSE;
/* Fill the whole background if needed */ if (bFill) { GetConsoleScreenBufferInfo(hOutput, &csbi);
coPos.X = 0; coPos.Y = 0; FillConsoleOutputAttribute(hOutput, wColor & 0x00FF, csbi.dwSize.X * csbi.dwSize.Y, coPos, &dwWritten); }
/* Set the text attribute */ SetConsoleTextAttribute(hOutput, wColor & 0x00FF); return TRUE;}#endif
#include <cjkcode.h>#include "wcwidth.c"
// NOTE: The check against 0x80 is to avoid calling the helper function// for characters that we already know are not full-width.#define IS_FULL_WIDTH(wch) \ (((USHORT)(wch) >= 0x0080) && (mk_wcwidth_cjk(wch) == 2))
SIZE_T ConGetTextWidthW(PCWSTR pszText){ SIZE_T ich, cxWidth;
if (!IsCJKCodePage(OutputCodePage)) return _tcslen(pszText);
for (ich = cxWidth = 0; pszText[ich]; ++ich) { if (IS_FULL_WIDTH(pszText[ich])) cxWidth += 2; else ++cxWidth; }
return cxWidth;}
SIZE_T ConGetTextWidthA(PCSTR pszText){ int cchMax; PWSTR pszWide; SIZE_T cxWidth;
cchMax = MultiByteToWideChar(OutputCodePage, 0, pszText, -1, NULL, 0); pszWide = cmd_alloc(cchMax * sizeof(WCHAR)); MultiByteToWideChar(OutputCodePage, 0, pszText, -1, pszWide, cchMax); cxWidth = ConGetTextWidthW(pszWide); cmd_free(pszWide); return cxWidth;}
/* EOF */