27 #if defined(_MSC_VER) && _MSC_VER < 1600
33 #ifndef COMMON_LVB_REVERSE_VIDEO
34 # define COMMON_LVB_REVERSE_VIDEO 0x4000
44 # define InterlockedOr _InterlockedOr
47 #define UNICODE_REPLACEMENT_CHARACTER (0xfffd)
49 #define ANSI_NORMAL 0x0000
50 #define ANSI_ESCAPE_SEEN 0x0002
51 #define ANSI_CSI 0x0004
52 #define ANSI_ST_CONTROL 0x0008
53 #define ANSI_IGNORE 0x0010
54 #define ANSI_IN_ARG 0x0020
55 #define ANSI_IN_STRING 0x0040
56 #define ANSI_BACKSLASH_SEEN 0x0080
57 #define ANSI_EXTENSION 0x0100
58 #define ANSI_DECSCUSR 0x0200
60 #define MAX_INPUT_BUFFER_LENGTH 8192
61 #define MAX_CONSOLE_CHAR 8192
63 #ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
64 #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
67 #define CURSOR_SIZE_SMALL 25
68 #define CURSOR_SIZE_LARGE 100
71 CONSOLE_SCREEN_BUFFER_INFO* screen_buffer_info,
72 CONSOLE_CURSOR_INFO* cursor_info);
140 DWORD dwmsEventTime);
151 FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
170 GENERIC_READ | GENERIC_WRITE,
177 CONSOLE_SCREEN_BUFFER_INFO sb_info;
180 WT_EXECUTELONGFUNCTION);
192 DWORD NumberOfEvents;
194 CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
195 CONSOLE_CURSOR_INFO cursor_info;
216 DUPLICATE_SAME_ACCESS))
221 readable = GetNumberOfConsoleInputEvents(
handle, &NumberOfEvents);
224 if (!GetConsoleScreenBufferInfo(
handle, &screen_buffer_info)) {
229 if (!GetConsoleCursorInfo(
handle, &cursor_info)) {
254 tty->reqs_pending = 0;
261 tty->tty.rd.unused_ = NULL;
263 tty->tty.rd.read_raw_wait = NULL;
266 tty->tty.rd.last_key_len = 0;
267 tty->tty.rd.last_key_offset = 0;
268 tty->tty.rd.last_utf16_high_surrogate = 0;
269 memset(&
tty->tty.rd.last_input_record, 0,
sizeof tty->tty.rd.last_input_record);
275 tty->tty.wr.utf8_bytes_left = 0;
276 tty->tty.wr.utf8_codepoint = 0;
279 tty->tty.wr.previous_eol = 0;
293 CONSOLE_SCREEN_BUFFER_INFO* screen_buffer_info,
294 CONSOLE_CURSOR_INFO* cursor_info) {
295 static int style_captured = 0;
352 unsigned char was_reading;
367 flags = ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
370 flags = ENABLE_WINDOW_INPUT;
394 if (!SetConsoleMode(
tty->handle,
flags)) {
418 CONSOLE_SCREEN_BUFFER_INFO info;
420 if (!GetConsoleScreenBufferInfo(
tty->handle, &info)) {
447 UnregisterWait(
handle->tty.rd.read_raw_wait);
448 handle->tty.rd.read_raw_wait = NULL;
467 memset(&
req->u.io.overlapped, 0,
sizeof(
req->u.io.overlapped));
469 r = RegisterWaitForSingleObject(&
handle->tty.rd.read_raw_wait,
474 WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
476 handle->tty.rd.read_raw_wait = NULL;
492 DWORD chars, read_chars;
495 BOOL read_console_success;
503 assert(
handle->tty.rd.read_line_buffer.base != NULL);
504 assert(
handle->tty.rd.read_line_buffer.len > 0);
520 req->u.io.overlapped.InternalHigh = 0;
525 read_console_success = ReadConsoleW(
handle->handle,
531 if (read_console_success) {
536 handle->tty.rd.read_line_buffer.base,
552 HANDLE active_screen_buffer;
553 active_screen_buffer = CreateFileA(
"conout$",
554 GENERIC_READ | GENERIC_WRITE,
555 FILE_SHARE_READ | FILE_SHARE_WRITE,
558 FILE_ATTRIBUTE_NORMAL,
570 SetConsoleCursorPosition(active_screen_buffer,
pos);
571 CloseHandle(active_screen_buffer);
590 memset(&
req->u.io.overlapped, 0,
sizeof(
req->u.io.overlapped));
594 if (
handle->tty.rd.read_line_buffer.base == NULL ||
595 handle->tty.rd.read_line_buffer.len == 0) {
598 &
handle->tty.rd.read_line_buffer);
601 assert(
handle->tty.rd.read_line_buffer.base != NULL);
610 WT_EXECUTELONGFUNCTION);
632 #define VK_CASE(vk, normal_str, shift_str, ctrl_str, shift_ctrl_str) \
634 if (shift && ctrl) { \
635 *len = sizeof shift_ctrl_str; \
636 return "\033" shift_ctrl_str; \
637 } else if (shift) { \
638 *len = sizeof shift_str ; \
639 return "\033" shift_str; \
641 *len = sizeof ctrl_str; \
642 return "\033" ctrl_str; \
644 *len = sizeof normal_str; \
645 return "\033" normal_str; \
653 VK_CASE(VK_INSERT,
"[2~",
"[2;2~",
"[2;5~",
"[2;6~")
654 VK_CASE(VK_END,
"[4~",
"[4;2~",
"[4;5~",
"[4;6~")
655 VK_CASE(VK_DOWN,
"[B",
"[1;2B",
"[1;5B",
"[1;6B")
656 VK_CASE(VK_NEXT,
"[6~",
"[6;2~",
"[6;5~",
"[6;6~")
657 VK_CASE(VK_LEFT,
"[D",
"[1;2D",
"[1;5D",
"[1;6D")
658 VK_CASE(VK_CLEAR,
"[G",
"[1;2G",
"[1;5G",
"[1;6G")
659 VK_CASE(VK_RIGHT,
"[C",
"[1;2C",
"[1;5C",
"[1;6C")
660 VK_CASE(VK_UP,
"[A",
"[1;2A",
"[1;5A",
"[1;6A")
661 VK_CASE(VK_HOME,
"[1~",
"[1;2~",
"[1;5~",
"[1;6~")
662 VK_CASE(VK_PRIOR,
"[5~",
"[5;2~",
"[5;5~",
"[5;6~")
663 VK_CASE(VK_DELETE,
"[3~",
"[3;2~",
"[3;5~",
"[3;6~")
664 VK_CASE(VK_NUMPAD0,
"[2~",
"[2;2~",
"[2;5~",
"[2;6~")
665 VK_CASE(VK_NUMPAD1,
"[4~",
"[4;2~",
"[4;5~",
"[4;6~")
666 VK_CASE(VK_NUMPAD2,
"[B",
"[1;2B",
"[1;5B",
"[1;6B")
667 VK_CASE(VK_NUMPAD3,
"[6~",
"[6;2~",
"[6;5~",
"[6;6~")
668 VK_CASE(VK_NUMPAD4,
"[D",
"[1;2D",
"[1;5D",
"[1;6D")
669 VK_CASE(VK_NUMPAD5,
"[G",
"[1;2G",
"[1;5G",
"[1;6G")
670 VK_CASE(VK_NUMPAD6,
"[C",
"[1;2C",
"[1;5C",
"[1;6C")
671 VK_CASE(VK_NUMPAD7,
"[A",
"[1;2A",
"[1;5A",
"[1;6A")
672 VK_CASE(VK_NUMPAD8,
"[1~",
"[1;2~",
"[1;5~",
"[1;6~")
673 VK_CASE(VK_NUMPAD9,
"[5~",
"[5;2~",
"[5;5~",
"[5;6~")
674 VK_CASE(VK_DECIMAL,
"[3~",
"[3;2~",
"[3;5~",
"[3;6~")
675 VK_CASE(VK_F1,
"[[A",
"[23~",
"[11^",
"[23^" )
676 VK_CASE(VK_F2,
"[[B",
"[24~",
"[12^",
"[24^" )
677 VK_CASE(VK_F3,
"[[C",
"[25~",
"[13^",
"[25^" )
678 VK_CASE(VK_F4,
"[[D",
"[26~",
"[14^",
"[26^" )
679 VK_CASE(VK_F5,
"[[E",
"[28~",
"[15^",
"[28^" )
680 VK_CASE(VK_F6,
"[17~",
"[29~",
"[17^",
"[29^" )
681 VK_CASE(VK_F7,
"[18~",
"[31~",
"[18^",
"[31^" )
682 VK_CASE(VK_F8,
"[19~",
"[32~",
"[19^",
"[32^" )
683 VK_CASE(VK_F9,
"[20~",
"[33~",
"[20^",
"[33^" )
684 VK_CASE(VK_F10,
"[21~",
"[34~",
"[21^",
"[34^" )
685 VK_CASE(VK_F11,
"[23~",
"[23$",
"[23^",
"[23@" )
686 VK_CASE(VK_F12,
"[24~",
"[24$",
"[24^",
"[24@" )
699 #define KEV handle->tty.rd.last_input_record.Event.KeyEvent
701 DWORD records_left, records_read;
705 assert(
handle->type == UV_TTY);
726 if (!GetNumberOfConsoleInputEvents(
handle->handle, &records_left)) {
740 while ((records_left > 0 ||
handle->tty.rd.last_key_len > 0) &&
742 if (
handle->tty.rd.last_key_len == 0) {
744 if (!ReadConsoleInputW(
handle->handle,
745 &
handle->tty.rd.last_input_record,
759 if (
handle->tty.rd.last_input_record.EventType == WINDOW_BUFFER_SIZE_EVENT) {
764 if (
handle->tty.rd.last_input_record.EventType != KEY_EVENT) {
771 (
KEV.wVirtualKeyCode != VK_MENU ||
772 KEV.uChar.UnicodeChar == 0)) {
779 if ((
KEV.dwControlKeyState & LEFT_ALT_PRESSED) &&
780 !(
KEV.dwControlKeyState & ENHANCED_KEY) &&
781 (
KEV.wVirtualKeyCode == VK_INSERT ||
782 KEV.wVirtualKeyCode == VK_END ||
783 KEV.wVirtualKeyCode == VK_DOWN ||
784 KEV.wVirtualKeyCode == VK_NEXT ||
785 KEV.wVirtualKeyCode == VK_LEFT ||
786 KEV.wVirtualKeyCode == VK_CLEAR ||
787 KEV.wVirtualKeyCode == VK_RIGHT ||
788 KEV.wVirtualKeyCode == VK_HOME ||
789 KEV.wVirtualKeyCode == VK_UP ||
790 KEV.wVirtualKeyCode == VK_PRIOR ||
791 KEV.wVirtualKeyCode == VK_NUMPAD0 ||
792 KEV.wVirtualKeyCode == VK_NUMPAD1 ||
793 KEV.wVirtualKeyCode == VK_NUMPAD2 ||
794 KEV.wVirtualKeyCode == VK_NUMPAD3 ||
795 KEV.wVirtualKeyCode == VK_NUMPAD4 ||
796 KEV.wVirtualKeyCode == VK_NUMPAD5 ||
797 KEV.wVirtualKeyCode == VK_NUMPAD6 ||
798 KEV.wVirtualKeyCode == VK_NUMPAD7 ||
799 KEV.wVirtualKeyCode == VK_NUMPAD8 ||
800 KEV.wVirtualKeyCode == VK_NUMPAD9)) {
804 if (
KEV.uChar.UnicodeChar != 0) {
805 int prefix_len, char_len;
808 if (
KEV.uChar.UnicodeChar >= 0xD800 &&
809 KEV.uChar.UnicodeChar < 0xDC00) {
811 handle->tty.rd.last_utf16_high_surrogate =
KEV.uChar.UnicodeChar;
817 if ((
KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
818 && !(
KEV.dwControlKeyState & (LEFT_CTRL_PRESSED |
819 RIGHT_CTRL_PRESSED)) &&
KEV.bKeyDown) {
820 handle->tty.rd.last_key[0] =
'\033';
826 if (
KEV.uChar.UnicodeChar >= 0xDC00 &&
827 KEV.uChar.UnicodeChar < 0xE000) {
829 WCHAR utf16_buffer[2];
830 utf16_buffer[0] =
handle->tty.rd.last_utf16_high_surrogate;
831 utf16_buffer[1] =
KEV.uChar.UnicodeChar;
832 char_len = WideCharToMultiByte(CP_UTF8,
836 &
handle->tty.rd.last_key[prefix_len],
837 sizeof handle->tty.rd.last_key,
842 char_len = WideCharToMultiByte(CP_UTF8,
844 &
KEV.uChar.UnicodeChar,
846 &
handle->tty.rd.last_key[prefix_len],
847 sizeof handle->tty.rd.last_key,
853 handle->tty.rd.last_utf16_high_surrogate = 0;
866 handle->tty.rd.last_key_len = (
unsigned char) (prefix_len + char_len);
867 handle->tty.rd.last_key_offset = 0;
873 size_t prefix_len, vt100_len;
876 !!(
KEV.dwControlKeyState & SHIFT_PRESSED),
877 !!(
KEV.dwControlKeyState & (
879 RIGHT_CTRL_PRESSED)),
888 if (
KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) {
889 handle->tty.rd.last_key[0] =
'\033';
896 assert(prefix_len + vt100_len < sizeof handle->
tty.rd.last_key);
897 memcpy(&
handle->tty.rd.last_key[prefix_len], vt100, vt100_len);
899 handle->tty.rd.last_key_len = (
unsigned char) (prefix_len + vt100_len);
900 handle->tty.rd.last_key_offset = 0;
905 if (
handle->tty.rd.last_key_offset <
handle->tty.rd.last_key_len) {
910 if (
buf.base == NULL ||
buf.len == 0) {
914 assert(
buf.base != NULL);
917 buf.base[buf_used++] =
handle->tty.rd.last_key[
handle->tty.rd.last_key_offset++];
920 if ((
size_t) buf_used ==
buf.len) {
930 if (--
KEV.wRepeatCount > 0) {
931 handle->tty.rd.last_key_offset = 0;
935 handle->tty.rd.last_key_len = 0;
963 assert(
handle->type == UV_TTY);
983 req->u.io.overlapped.InternalHigh != 0) {
985 DWORD
bytes =
req->u.io.overlapped.InternalHigh;
1003 assert(
handle->type == UV_TTY);
1009 if (
handle->tty.rd.read_line_buffer.len == 0) {
1022 return ERROR_INVALID_PARAMETER;
1038 if (
handle->tty.rd.last_key_len > 0) {
1054 INPUT_RECORD record;
1066 memset(&record, 0,
sizeof record);
1067 record.EventType = FOCUS_EVENT;
1068 if (!WriteConsoleInputW(
handle->handle, &record, 1, &written)) {
1069 return GetLastError();
1085 INPUT_RECORD record;
1106 active_screen_buffer = CreateFileA(
"conout$",
1107 GENERIC_READ | GENERIC_WRITE,
1108 FILE_SHARE_READ | FILE_SHARE_WRITE,
1111 FILE_ATTRIBUTE_NORMAL,
1115 GetConsoleScreenBufferInfo(active_screen_buffer,
1121 record.EventType = KEY_EVENT;
1122 record.Event.KeyEvent.bKeyDown =
TRUE;
1123 record.Event.KeyEvent.wRepeatCount = 1;
1124 record.Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
1125 record.Event.KeyEvent.wVirtualScanCode =
1126 MapVirtualKeyW(VK_RETURN, MAPVK_VK_TO_VSC);
1127 record.Event.KeyEvent.uChar.UnicodeChar =
L'\r';
1128 record.Event.KeyEvent.dwControlKeyState = 0;
1129 if (!WriteConsoleInputW(
handle->handle, &record, 1, &written))
1130 err = GetLastError();
1133 CloseHandle(active_screen_buffer);
1146 }
else if (uv_tty_virtual_offset < info->dwCursorPosition.Y -
1163 CONSOLE_SCREEN_BUFFER_INFO* info,
int x,
unsigned char x_relative,
int y,
1164 unsigned char y_relative) {
1171 y = info->dwCursorPosition.Y +
y;
1184 x = info->dwCursorPosition.X +
x;
1193 result.X = (
unsigned short)
x;
1194 result.Y = (
unsigned short)
y;
1203 if (*
error != ERROR_SUCCESS) {
1207 if (!WriteConsoleW(
handle->handle,
1212 *
error = GetLastError();
1221 int y,
unsigned char y_relative, DWORD*
error) {
1222 CONSOLE_SCREEN_BUFFER_INFO info;
1225 if (*
error != ERROR_SUCCESS) {
1230 if (!GetConsoleScreenBufferInfo(
handle->handle, &info)) {
1231 *
error = GetLastError();
1236 if (!SetConsoleCursorPosition(
handle->handle,
pos)) {
1237 if (GetLastError() == ERROR_INVALID_PARAMETER) {
1241 *
error = GetLastError();
1251 const COORD
origin = {0, 0};
1253 CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
1254 DWORD
count, written;
1256 if (*
error != ERROR_SUCCESS) {
1261 if (!SetConsoleTextAttribute(
handle->handle, char_attrs)) {
1262 *
error = GetLastError();
1267 if (!SetConsoleCursorPosition(
handle->handle,
origin)) {
1268 *
error = GetLastError();
1274 if (!GetConsoleScreenBufferInfo(
handle->handle, &screen_buffer_info)) {
1275 *
error = GetLastError();
1279 count = screen_buffer_info.dwSize.X * screen_buffer_info.dwSize.Y;
1281 if (!(FillConsoleOutputCharacterW(
handle->handle,
1286 FillConsoleOutputAttribute(
handle->handle,
1291 if (GetLastError() == ERROR_INVALID_PARAMETER) {
1295 *
error = GetLastError();
1306 *
error = GetLastError();
1316 CONSOLE_SCREEN_BUFFER_INFO info;
1318 DWORD
count, written;
1321 int x1r, x2r, y1r, y2r;
1323 if (*
error != ERROR_SUCCESS) {
1348 if (!entire_screen) {
1361 if (!GetConsoleScreenBufferInfo(
handle->handle, &info)) {
1362 *
error = GetLastError();
1371 if (!(FillConsoleOutputCharacterW(
handle->handle,
1376 FillConsoleOutputAttribute(
handle->handle,
1381 if (GetLastError() == ERROR_INVALID_PARAMETER) {
1385 *
error = GetLastError();
1395 WORD fg = info.wAttributes & 0xF; \
1396 WORD bg = info.wAttributes & 0xF0; \
1397 info.wAttributes &= 0xFF00; \
1398 info.wAttributes |= fg << 4; \
1399 info.wAttributes |= bg >> 4; \
1403 unsigned short argc =
handle->tty.wr.ansi_csi_argc;
1404 unsigned short* argv =
handle->tty.wr.ansi_csi_argv;
1406 CONSOLE_SCREEN_BUFFER_INFO info;
1408 char fg_color = -1, bg_color = -1;
1409 char fg_bright = -1, bg_bright = -1;
1421 for (
i = 0;
i < argc;
i++) {
1422 short arg = argv[
i];
1432 }
else if (
arg == 1) {
1436 }
else if (
arg == 2) {
1441 }
else if (
arg == 5) {
1445 }
else if (
arg == 7) {
1449 }
else if (
arg == 21 ||
arg == 22) {
1453 }
else if (
arg == 25) {
1457 }
else if (
arg == 27) {
1461 }
else if (
arg >= 30 &&
arg <= 37) {
1463 fg_color =
arg - 30;
1465 }
else if (
arg == 39) {
1470 }
else if (
arg >= 40 &&
arg <= 47) {
1472 bg_color =
arg - 40;
1474 }
else if (
arg == 49) {
1479 }
else if (
arg >= 90 &&
arg <= 97) {
1482 fg_color =
arg - 90;
1484 }
else if (
arg >= 100 &&
arg <= 107) {
1487 bg_color =
arg - 100;
1492 if (fg_color == -1 && bg_color == -1 && fg_bright == -1 &&
1493 bg_bright == -1 && inverse == -1) {
1498 if (!GetConsoleScreenBufferInfo(
handle->handle, &info)) {
1499 *
error = GetLastError();
1507 if (fg_color != -1) {
1508 info.wAttributes &= ~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
1509 if (fg_color & 1) info.wAttributes |= FOREGROUND_RED;
1510 if (fg_color & 2) info.wAttributes |= FOREGROUND_GREEN;
1511 if (fg_color & 4) info.wAttributes |= FOREGROUND_BLUE;
1514 if (fg_bright != -1) {
1516 info.wAttributes |= FOREGROUND_INTENSITY;
1518 info.wAttributes &= ~FOREGROUND_INTENSITY;
1522 if (bg_color != -1) {
1523 info.wAttributes &= ~(BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
1524 if (bg_color & 1) info.wAttributes |= BACKGROUND_RED;
1525 if (bg_color & 2) info.wAttributes |= BACKGROUND_GREEN;
1526 if (bg_color & 4) info.wAttributes |= BACKGROUND_BLUE;
1529 if (bg_bright != -1) {
1531 info.wAttributes |= BACKGROUND_INTENSITY;
1533 info.wAttributes &= ~BACKGROUND_INTENSITY;
1537 if (inverse != -1) {
1549 if (!SetConsoleTextAttribute(
handle->handle, info.wAttributes)) {
1550 *
error = GetLastError();
1560 CONSOLE_SCREEN_BUFFER_INFO info;
1562 if (*
error != ERROR_SUCCESS) {
1566 if (!GetConsoleScreenBufferInfo(
handle->handle, &info)) {
1567 *
error = GetLastError();
1573 handle->tty.wr.saved_position.X = info.dwCursorPosition.X;
1577 if (save_attributes) {
1578 handle->tty.wr.saved_attributes = info.wAttributes &
1579 (FOREGROUND_INTENSITY | BACKGROUND_INTENSITY);
1588 unsigned char restore_attributes, DWORD*
error) {
1589 CONSOLE_SCREEN_BUFFER_INFO info;
1590 WORD new_attributes;
1592 if (*
error != ERROR_SUCCESS) {
1598 handle->tty.wr.saved_position.X,
1600 handle->tty.wr.saved_position.Y,
1607 if (restore_attributes &&
1609 if (!GetConsoleScreenBufferInfo(
handle->handle, &info)) {
1610 *
error = GetLastError();
1614 new_attributes = info.wAttributes;
1615 new_attributes &= ~(FOREGROUND_INTENSITY | BACKGROUND_INTENSITY);
1616 new_attributes |=
handle->tty.wr.saved_attributes;
1618 if (!SetConsoleTextAttribute(
handle->handle, new_attributes)) {
1619 *
error = GetLastError();
1630 CONSOLE_CURSOR_INFO cursor_info;
1632 if (!GetConsoleCursorInfo(
handle->handle, &cursor_info)) {
1633 *
error = GetLastError();
1637 cursor_info.bVisible = visible;
1639 if (!SetConsoleCursorInfo(
handle->handle, &cursor_info)) {
1640 *
error = GetLastError();
1648 CONSOLE_CURSOR_INFO cursor_info;
1650 if (!GetConsoleCursorInfo(
handle->handle, &cursor_info)) {
1651 *
error = GetLastError();
1657 }
else if (style <= 2) {
1663 if (!SetConsoleCursorInfo(
handle->handle, &cursor_info)) {
1664 *
error = GetLastError();
1679 DWORD utf16_buf_used = 0;
1682 #define FLUSH_TEXT() \
1684 if (utf16_buf_used > 0) { \
1685 uv_tty_emit_text(handle, utf16_buf, utf16_buf_used, error); \
1686 utf16_buf_used = 0; \
1690 #define ENSURE_BUFFER_SPACE(wchars_needed) \
1691 if (wchars_needed > ARRAY_SIZE(utf16_buf) - utf16_buf_used) { \
1696 unsigned char utf8_bytes_left =
handle->tty.wr.utf8_bytes_left;
1697 unsigned int utf8_codepoint =
handle->tty.wr.utf8_codepoint;
1698 unsigned char previous_eol =
handle->tty.wr.previous_eol;
1699 unsigned short ansi_parser_state =
handle->tty.wr.ansi_parser_state;
1703 *
error = ERROR_SUCCESS;
1707 for (
i = 0;
i < nbufs;
i++) {
1711 for (j = 0; j <
buf.len; j++) {
1712 unsigned char c =
buf.base[j];
1717 if (utf8_bytes_left == 0) {
1719 DWORD first_zero_bit;
1720 unsigned char not_c = ~
c;
1722 if (_BitScanReverse(&first_zero_bit, not_c)) {
1725 first_zero_bit = (
sizeof(
int) * 8) - 1 - __builtin_clz(not_c);
1727 if (first_zero_bit == 7) {
1729 utf8_codepoint = (
unsigned int)
c;
1731 }
else if (first_zero_bit <= 5) {
1733 utf8_codepoint = (0xff >> (8 - first_zero_bit)) &
c;
1734 utf8_bytes_left = (char) (6 - first_zero_bit);
1746 }
else if ((
c & 0xc0) == 0x80) {
1749 utf8_codepoint <<= 6;
1750 utf8_codepoint |= ((
unsigned int)
c & 0x3f);
1754 utf8_bytes_left = 0;
1762 if (utf8_bytes_left != 0) {
1770 switch (utf8_codepoint) {
1777 handle->tty.wr.ansi_csi_argc = 0;
1782 switch (utf8_codepoint) {
1785 handle->tty.wr.ansi_csi_argc = 0;
1823 if (utf8_codepoint >=
'@' && utf8_codepoint <=
'_') {
1835 if (utf8_codepoint >=
'@' && utf8_codepoint <=
'~') {
1843 if (utf8_codepoint >=
'@' && utf8_codepoint <=
'~') {
1845 if (utf8_codepoint ==
'q') {
1847 int style =
handle->tty.wr.ansi_csi_argc
1848 ?
handle->tty.wr.ansi_csi_argv[0] : 1;
1849 if (style >= 0 && style <= 6) {
1863 }
else if (ansi_parser_state &
ANSI_CSI) {
1867 if (utf8_codepoint >=
'0' && utf8_codepoint <=
'9') {
1872 if (
handle->tty.wr.ansi_csi_argc >=
1878 handle->tty.wr.ansi_csi_argc++;
1879 handle->tty.wr.ansi_csi_argv[
handle->tty.wr.ansi_csi_argc - 1] =
1880 (
unsigned short) utf8_codepoint -
'0';
1886 handle->tty.wr.ansi_csi_argv[
handle->tty.wr.ansi_csi_argc - 1];
1894 handle->tty.wr.ansi_csi_argv[
handle->tty.wr.ansi_csi_argc - 1] =
1895 (
unsigned short)
value + (utf8_codepoint -
'0');
1899 }
else if (utf8_codepoint ==
';') {
1910 if (
handle->tty.wr.ansi_csi_argc >=
1917 handle->tty.wr.ansi_csi_argc++;
1918 handle->tty.wr.ansi_csi_argv[
handle->tty.wr.ansi_csi_argc - 1] = 0;
1922 }
else if (utf8_codepoint ==
'?' &&
1925 handle->tty.wr.ansi_csi_argc == 0) {
1932 }
else if (utf8_codepoint ==
' ' &&
1939 }
else if (utf8_codepoint >=
'@' && utf8_codepoint <=
'~') {
1943 switch (utf8_codepoint) {
1946 if (
handle->tty.wr.ansi_csi_argc == 1 &&
1947 handle->tty.wr.ansi_csi_argv[0] == 25) {
1955 if (
handle->tty.wr.ansi_csi_argc == 1 &&
1956 handle->tty.wr.ansi_csi_argv[0] == 25) {
1966 switch (utf8_codepoint) {
1970 y = -(
handle->tty.wr.ansi_csi_argc
1971 ?
handle->tty.wr.ansi_csi_argv[0] : 1);
1978 y =
handle->tty.wr.ansi_csi_argc
1979 ?
handle->tty.wr.ansi_csi_argv[0] : 1;
1986 x =
handle->tty.wr.ansi_csi_argc
1987 ?
handle->tty.wr.ansi_csi_argv[0] : 1;
1994 x = -(
handle->tty.wr.ansi_csi_argc
1995 ?
handle->tty.wr.ansi_csi_argv[0] : 1);
2002 y =
handle->tty.wr.ansi_csi_argc
2003 ?
handle->tty.wr.ansi_csi_argv[0] : 1;
2010 y = -(
handle->tty.wr.ansi_csi_argc
2011 ?
handle->tty.wr.ansi_csi_argv[0] : 1);
2018 x = (
handle->tty.wr.ansi_csi_argc >= 1 &&
2019 handle->tty.wr.ansi_csi_argv[0])
2020 ?
handle->tty.wr.ansi_csi_argv[0] - 1 : 0;
2028 y = (
handle->tty.wr.ansi_csi_argc >= 1 &&
2029 handle->tty.wr.ansi_csi_argv[0])
2030 ?
handle->tty.wr.ansi_csi_argv[0] - 1 : 0;
2031 x = (
handle->tty.wr.ansi_csi_argc >= 2 &&
2032 handle->tty.wr.ansi_csi_argv[1])
2033 ?
handle->tty.wr.ansi_csi_argv[1] - 1 : 0;
2040 d =
handle->tty.wr.ansi_csi_argc
2041 ?
handle->tty.wr.ansi_csi_argv[0] : 0;
2042 if (
d >= 0 &&
d <= 2) {
2050 d =
handle->tty.wr.ansi_csi_argc
2051 ?
handle->tty.wr.ansi_csi_argv[0] : 0;
2052 if (
d >= 0 &&
d <= 2) {
2093 if (utf8_codepoint ==
'"') {
2095 }
else if (utf8_codepoint ==
'\\') {
2102 if (utf8_codepoint ==
'\007' || (utf8_codepoint ==
'\\' &&
2106 }
else if (utf8_codepoint ==
'\033') {
2109 }
else if (utf8_codepoint ==
'"') {
2127 if (utf8_codepoint > 0xffff) {
2131 if (utf8_codepoint == 0x0a || utf8_codepoint == 0x0d) {
2134 if (utf8_codepoint == 0x0a && previous_eol != 0x0d) {
2137 utf16_buf[utf16_buf_used++] =
L'\r';
2138 utf16_buf[utf16_buf_used++] =
L'\n';
2139 }
else if (utf8_codepoint == 0x0d && previous_eol == 0x0a) {
2147 utf16_buf[utf16_buf_used++] = (WCHAR) utf8_codepoint;
2150 previous_eol = (char) utf8_codepoint;
2152 }
else if (utf8_codepoint <= 0xffff) {
2155 utf16_buf[utf16_buf_used++] = (WCHAR) utf8_codepoint;
2165 handle->tty.wr.utf8_bytes_left = utf8_bytes_left;
2166 handle->tty.wr.utf8_codepoint = utf8_codepoint;
2167 handle->tty.wr.previous_eol = previous_eol;
2168 handle->tty.wr.ansi_parser_state = ansi_parser_state;
2195 handle->stream.conn.write_reqs_pending++;
2198 req->u.io.queued_bytes = 0;
2214 unsigned int nbufs) {
2217 if (
handle->stream.conn.write_reqs_pending > 0)
2231 handle->write_queue_size -=
req->u.io.queued_bytes;
2239 handle->stream.conn.write_reqs_pending--;
2240 if (
handle->stream.conn.shutdown_req != NULL &&
2241 handle->stream.conn.write_reqs_pending == 0) {
2255 CloseHandle(
handle->handle);
2264 if (
handle->reqs_pending == 0) {
2272 handle->stream.conn.shutdown_req != NULL &&
2273 handle->stream.conn.write_reqs_pending == 0) {
2277 if (
handle->stream.conn.shutdown_req->cb) {
2279 handle->stream.conn.shutdown_req->cb(
handle->stream.conn.shutdown_req, UV_ECANCELED);
2281 handle->stream.conn.shutdown_req->cb(
handle->stream.conn.shutdown_req, 0);
2285 handle->stream.conn.shutdown_req = NULL;
2292 handle->reqs_pending == 0) {
2296 handle->tty.rd.read_raw_wait == NULL);
2337 if (!GetConsoleMode(
handle, &dwMode)) {
2342 if (!SetConsoleMode(
handle, dwMode)) {
2351 ULONG_PTR conhost_pid;
2360 sizeof(conhost_pid),
2371 conhost_pid &= ~(ULONG_PTR)0x3;
2378 WT_EXECUTELONGFUNCTION) == 0)
2382 EVENT_CONSOLE_LAYOUT,
2387 WINEVENT_OUTOFCONTEXT))
2390 while (GetMessage(&
msg, NULL, 0, 0)) {
2391 TranslateMessage(&
msg);
2392 DispatchMessage(&
msg);
2402 DWORD dwEventThread,
2403 DWORD dwmsEventTime) {
2418 CONSOLE_SCREEN_BUFFER_INFO sb_info;
2424 width = sb_info.dwSize.X;
2425 height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1;