static COORD uv_tty_make_real_coord(uv_tty_t* handle, CONSOLE_SCREEN_BUFFER_INFO* info, int x, unsigned char x_relative, int y, unsigned char y_relative) { COORD result; uv_tty_update_virtual_window(info); /* Adjust y position */ if (y_relative) { y = info->dwCursorPosition.Y + y; } else { y = uv_tty_virtual_offset + y; } /* Clip y to virtual client rectangle */ if (y < uv_tty_virtual_offset) { y = uv_tty_virtual_offset; } else if (y >= uv_tty_virtual_offset + uv_tty_virtual_height) { y = uv_tty_virtual_offset + uv_tty_virtual_height - 1; } /* Adjust x */ if (x_relative) { x = info->dwCursorPosition.X + x; } /* Clip x */ if (x < 0) { x = 0; } else if (x >= uv_tty_virtual_width) { x = uv_tty_virtual_width - 1; } result.X = (unsigned short) x; result.Y = (unsigned short) y; return result; }
int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd) { HANDLE win_handle; CONSOLE_SCREEN_BUFFER_INFO info; win_handle = (HANDLE) _get_osfhandle(fd); if (win_handle == INVALID_HANDLE_VALUE) { uv_set_sys_error(loop, ERROR_INVALID_HANDLE); return -1; } if (!GetConsoleMode(win_handle, &tty->original_console_mode)) { uv_set_sys_error(loop, GetLastError()); return -1; } /* Initialize virtual window size; if it fails, assume that this is stdin. */ if (GetConsoleScreenBufferInfo(win_handle, &info)) { EnterCriticalSection(&uv_tty_output_lock); uv_tty_update_virtual_window(&info); LeaveCriticalSection(&uv_tty_output_lock); } uv_stream_init(loop, (uv_stream_t*) tty); uv_connection_init((uv_stream_t*) tty); tty->type = UV_TTY; tty->handle = win_handle; tty->read_line_handle = NULL; tty->read_line_buffer = uv_null_buf_; tty->read_raw_wait = NULL; tty->reqs_pending = 0; tty->flags |= UV_HANDLE_BOUND; /* Init keycode-to-vt100 mapper state. */ tty->last_key_len = 0; tty->last_key_offset = 0; tty->last_utf16_high_surrogate = 0; memset(&tty->last_input_record, 0, sizeof tty->last_input_record); /* Init utf8-to-utf16 conversion state. */ tty->utf8_bytes_left = 0; tty->utf8_codepoint = 0; /* Initialize eol conversion state */ tty->previous_eol = 0; /* Init ANSI parser state. */ tty->ansi_parser_state = ANSI_NORMAL; return 0; }
int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) { CONSOLE_SCREEN_BUFFER_INFO info; if (!GetConsoleScreenBufferInfo(tty->handle, &info)) { uv_set_sys_error(tty->loop, GetLastError()); return -1; } EnterCriticalSection(&uv_tty_output_lock); uv_tty_update_virtual_window(&info); LeaveCriticalSection(&uv_tty_output_lock); *width = uv_tty_virtual_width; *height = uv_tty_virtual_height; return 0; }
int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) { HANDLE handle = INVALID_HANDLE_VALUE; DWORD original_console_mode = 0; CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info; handle = (HANDLE) _get_osfhandle(fd); if (handle == INVALID_HANDLE_VALUE) { uv__set_artificial_error(loop, UV_EBADF); return -1; } if (readable) { /* Try to obtain the original console mode fromt he input handle. */ if (!GetConsoleMode(handle, &original_console_mode)) { uv__set_sys_error(loop, GetLastError()); return -1; } } else { /* Obtain the screen buffer info with the output handle. */ if (!GetConsoleScreenBufferInfo(handle, &screen_buffer_info)) { uv__set_sys_error(loop, GetLastError()); return -1; } /* Obtain the the tty_output_lock because the virtual window state is */ /* shared between all uv_tty_t handles. */ EnterCriticalSection(&uv_tty_output_lock); /* Store the global tty output handle. This handle is used by TTY read */ /* streams to update the virtual window when a CONSOLE_BUFFER_SIZE_EVENT */ /* is received. */ uv_tty_output_handle = handle; uv_tty_update_virtual_window(&screen_buffer_info); LeaveCriticalSection(&uv_tty_output_lock); } uv_stream_init(loop, (uv_stream_t*) tty, UV_TTY); uv_connection_init((uv_stream_t*) tty); tty->handle = handle; tty->reqs_pending = 0; tty->flags |= UV_HANDLE_BOUND; if (readable) { /* Initialize TTY input specific fields. */ tty->original_console_mode = original_console_mode; tty->flags |= UV_HANDLE_TTY_READABLE | UV_HANDLE_READABLE; tty->read_line_handle = NULL; tty->read_line_buffer = uv_null_buf_; tty->read_raw_wait = NULL; /* Init keycode-to-vt100 mapper state. */ tty->last_key_len = 0; tty->last_key_offset = 0; tty->last_utf16_high_surrogate = 0; memset(&tty->last_input_record, 0, sizeof tty->last_input_record); } else { /* TTY output specific fields. */ tty->flags |= UV_HANDLE_WRITABLE; /* Init utf8-to-utf16 conversion state. */ tty->utf8_bytes_left = 0; tty->utf8_codepoint = 0; /* Initialize eol conversion state */ tty->previous_eol = 0; /* Init ANSI parser state. */ tty->ansi_parser_state = ANSI_NORMAL; } return 0; }