LPSTR AnsiText(LPCWSTR strw, enum set_encoding_id encoding) { LPSTR str = NULL; UINT codepage = WinGetCodepage(encoding); int length; /* get length of converted string */ length = WideCharToMultiByte(codepage, 0, strw, -1, NULL, 0, NULL, 0); str = (LPSTR) malloc(sizeof(char) * length); /* convert string to "Ansi" */ length = WideCharToMultiByte(codepage, 0, strw, -1, str, length, NULL, 0); return str; }
LPWSTR UnicodeText(LPCSTR str, enum set_encoding_id encoding) { LPWSTR strw = NULL; UINT codepage = WinGetCodepage(encoding); int length; /* sanity check */ if (str == NULL) return NULL; /* get length of converted string */ length = MultiByteToWideChar(codepage, 0, str, -1, NULL, 0); strw = (LPWSTR) malloc(sizeof(WCHAR) * length); /* convert string to UTF-16 */ length = MultiByteToWideChar(codepage, 0, str, -1, strw, length); return strw; }
void MultiByteAccumulate(BYTE ch, LPWSTR wstr, int * count) { static char mbstr[4] = ""; static int mbwait = 0; static int mbcount = 0; *count = 0; /* try to re-sync on control characters */ /* works for utf8 and sjis */ if (ch < 32) { mbwait = mbcount = 0; mbstr[0] = NUL; } if (encoding == S_ENC_UTF8) { /* combine UTF8 byte sequences */ if (mbwait == 0) { /* first byte */ mbcount = 0; mbstr[mbcount] = ch; if ((ch & 0xE0) == 0xC0) { // expect one more byte mbwait = 1; } else if ((ch & 0xF0) == 0xE0) { // expect two more bytes mbwait = 2; } else if ((ch & 0xF8) == 0xF0) { // expect three more bytes mbwait = 3; } } else { /* subsequent byte */ /*assert((ch & 0xC0) == 0x80);*/ if ((ch & 0xC0) == 0x80) { mbcount++; mbwait--; } else { /* invalid sequence */ mbcount = 0; mbwait = 0; } mbstr[mbcount] = ch; } if (mbwait == 0) { *count = MultiByteToWideChar(CP_UTF8, 0, mbstr, mbcount + 1, wstr, 2); } } else if (encoding == S_ENC_SJIS) { /* combine S-JIS sequences */ if (mbwait == 0) { /* first or single byte */ mbcount = 0; mbstr[mbcount] = ch; if (is_sjis_lead_byte(ch)) { /* first byte */ mbwait = 1; } } else { if ((ch >= 0x40) && (ch <= 0xfc)) { /* valid */ mbcount++; } else { /* invalid */ mbcount = 0; } mbwait = 0; /* max. double byte sequences */ mbstr[mbcount] = ch; } if (mbwait == 0) { *count = MultiByteToWideChar(932, 0, mbstr, mbcount + 1, wstr, 2); } } else { mbcount = 0; mbwait = 0; mbstr[0] = (char) ch; *count = MultiByteToWideChar(WinGetCodepage(encoding), 0, mbstr, mbcount + 1, wstr, 2); } }
int ConsoleReadCh() { const int max_input = 8; static char console_input[8]; static int first_input_char = 0; static int last_input_char = 0; INPUT_RECORD rec; DWORD recRead; HANDLE h; if (first_input_char != last_input_char) { int c = console_input[first_input_char]; first_input_char++; first_input_char %= max_input; return c; } h = GetStdHandle(STD_INPUT_HANDLE); if (h == NULL) return NUL; ReadConsoleInputW(h, &rec, 1, &recRead); /* FIXME: We should handle rec.Event.KeyEvent.wRepeatCount > 1, too. */ if (recRead == 1 && rec.EventType == KEY_EVENT && rec.Event.KeyEvent.bKeyDown && (rec.Event.KeyEvent.wVirtualKeyCode < VK_SHIFT || rec.Event.KeyEvent.wVirtualKeyCode > VK_MENU)) { if (rec.Event.KeyEvent.uChar.UnicodeChar) { if ((rec.Event.KeyEvent.dwControlKeyState == SHIFT_PRESSED) && (rec.Event.KeyEvent.wVirtualKeyCode == VK_TAB)) { return 034; /* remap Shift-Tab */ } else { int i, count; char mbchar[8]; count = WideCharToMultiByte(WinGetCodepage(encoding), 0, &rec.Event.KeyEvent.uChar.UnicodeChar, 1, mbchar, sizeof(mbchar), NULL, NULL); for (i = 1; i < count; i++) { console_input[last_input_char] = mbchar[i]; last_input_char++; last_input_char %= max_input; } return mbchar[0]; } } else { switch (rec.Event.KeyEvent.wVirtualKeyCode) { case VK_UP: return 020; case VK_DOWN: return 016; case VK_LEFT: return 002; case VK_RIGHT: return 006; case VK_HOME: return 001; case VK_END: return 005; case VK_DELETE: return 0117; } } } /* Error reading event or, key up or, one of the following event records: MOUSE_EVENT_RECORD, WINDOW_BUFFER_SIZE_RECORD, MENU_EVENT_RECORD, FOCUS_EVENT_RECORD */ return NUL; }