win: implement tty
loose end: line-buffered input reads ascii, not unicode
This commit is contained in:
parent
77bc00e9ad
commit
622eb99113
@ -182,6 +182,31 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
|
||||
struct { uv_pipe_connection_fields }; \
|
||||
};
|
||||
|
||||
/* TODO: put the parser states in an union - TTY handles are always */
|
||||
/* half-duplex so read-state can safely overlap write-state. */
|
||||
#define UV_TTY_PRIVATE_FIELDS \
|
||||
HANDLE handle; \
|
||||
HANDLE read_line_handle; \
|
||||
uv_buf_t read_line_buffer; \
|
||||
HANDLE read_raw_wait; \
|
||||
DWORD original_console_mode; \
|
||||
/* Fields used for translating win */ \
|
||||
/* keystrokes into vt100 characters */ \
|
||||
char last_key[8]; \
|
||||
unsigned char last_key_offset; \
|
||||
unsigned char last_key_len; \
|
||||
INPUT_RECORD last_input_record; \
|
||||
WCHAR last_utf16_high_surrogate; \
|
||||
/* utf8-to-utf16 conversion state */ \
|
||||
unsigned char utf8_bytes_left; \
|
||||
unsigned int utf8_codepoint; \
|
||||
/* eol conversion state */ \
|
||||
unsigned char previous_eol; \
|
||||
/* ansi parser state */ \
|
||||
unsigned char ansi_parser_state; \
|
||||
unsigned char ansi_csi_argc; \
|
||||
unsigned short ansi_csi_argv[4];
|
||||
|
||||
#define UV_TIMER_PRIVATE_FIELDS \
|
||||
RB_ENTRY(uv_timer_s) tree_entry; \
|
||||
int64_t due; \
|
||||
@ -274,8 +299,6 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
|
||||
int is_path_dir; \
|
||||
char* buffer;
|
||||
|
||||
#define UV_TTY_PRIVATE_FIELDS /* empty */
|
||||
|
||||
int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size,
|
||||
char* utf8Buffer, size_t utf8Size);
|
||||
int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer,
|
||||
|
||||
@ -48,6 +48,9 @@ static void uv_init(void) {
|
||||
|
||||
/* Initialize FS */
|
||||
uv_fs_init();
|
||||
|
||||
/* Initialize console */
|
||||
uv_console_init();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -20,11 +20,36 @@
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <io.h>
|
||||
|
||||
#include "uv.h"
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
uv_handle_type uv_guess_handle(uv_file file) {
|
||||
HANDLE handle = (HANDLE) _get_osfhandle(file);
|
||||
DWORD mode;
|
||||
|
||||
switch (GetFileType(handle)) {
|
||||
case FILE_TYPE_CHAR:
|
||||
if (GetConsoleMode(handle, &mode)) {
|
||||
return UV_TTY;
|
||||
} else {
|
||||
return UV_UNKNOWN_HANDLE;
|
||||
}
|
||||
|
||||
case FILE_TYPE_PIPE:
|
||||
return UV_NAMED_PIPE;
|
||||
|
||||
case FILE_TYPE_DISK:
|
||||
return UV_FILE;
|
||||
|
||||
default:
|
||||
return UV_UNKNOWN_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int uv_is_active(uv_handle_t* handle) {
|
||||
switch (handle->type) {
|
||||
case UV_TIMER:
|
||||
|
||||
@ -64,6 +64,7 @@ void uv_process_timers(uv_loop_t* loop);
|
||||
#define UV_HANDLE_UV_ALLOCED 0x20000
|
||||
#define UV_HANDLE_SYNC_BYPASS_IOCP 0x40000
|
||||
#define UV_HANDLE_ZERO_READ 0x80000
|
||||
#define UV_HANDLE_TTY_RAW 0x100000
|
||||
|
||||
void uv_want_endgame(uv_loop_t* loop, uv_handle_t* handle);
|
||||
void uv_process_endgames(uv_loop_t* loop);
|
||||
@ -173,6 +174,30 @@ void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle,
|
||||
void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
|
||||
uv_shutdown_t* req);
|
||||
|
||||
|
||||
/*
|
||||
* TTY
|
||||
*/
|
||||
void uv_console_init();
|
||||
|
||||
int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
|
||||
uv_read_cb read_cb);
|
||||
int uv_tty_read_stop(uv_tty_t* handle);
|
||||
int uv_tty_write(uv_loop_t* loop, uv_write_t* req, uv_tty_t* handle,
|
||||
uv_buf_t bufs[], int bufcnt, uv_write_cb cb);
|
||||
|
||||
void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle,
|
||||
uv_req_t* req);
|
||||
void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
|
||||
uv_write_t* req);
|
||||
/* TODO: remove me */
|
||||
void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle,
|
||||
uv_req_t* raw_req);
|
||||
/* TODO: remove me */
|
||||
void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle,
|
||||
uv_connect_t* req);
|
||||
|
||||
|
||||
/*
|
||||
* Loop watchers
|
||||
*/
|
||||
|
||||
@ -87,6 +87,12 @@ static uv_req_t* uv_remove_pending_req(uv_loop_t* loop) {
|
||||
req); \
|
||||
break; \
|
||||
\
|
||||
case UV_TTY: \
|
||||
uv_process_tty_##method##_req(loop, \
|
||||
(uv_tty_t*) ((req)->handle_at), \
|
||||
req); \
|
||||
break; \
|
||||
\
|
||||
default: \
|
||||
assert(0); \
|
||||
} \
|
||||
|
||||
@ -83,6 +83,8 @@ int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb,
|
||||
return uv_tcp_read_start((uv_tcp_t*)handle, alloc_cb, read_cb);
|
||||
case UV_NAMED_PIPE:
|
||||
return uv_pipe_read_start((uv_pipe_t*)handle, alloc_cb, read_cb);
|
||||
case UV_TTY:
|
||||
return uv_tty_read_start((uv_tty_t*) handle, alloc_cb, read_cb);
|
||||
default:
|
||||
assert(0);
|
||||
return -1;
|
||||
@ -91,9 +93,12 @@ int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb,
|
||||
|
||||
|
||||
int uv_read_stop(uv_stream_t* handle) {
|
||||
handle->flags &= ~UV_HANDLE_READING;
|
||||
|
||||
return 0;
|
||||
if (handle->type = UV_TTY) {
|
||||
return uv_tty_read_stop((uv_tty_t*) handle);
|
||||
} else {
|
||||
handle->flags &= ~UV_HANDLE_READING;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -106,6 +111,8 @@ int uv_write(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], int bufcnt,
|
||||
return uv_tcp_write(loop, req, (uv_tcp_t*) handle, bufs, bufcnt, cb);
|
||||
case UV_NAMED_PIPE:
|
||||
return uv_pipe_write(loop, req, (uv_pipe_t*) handle, bufs, bufcnt, cb);
|
||||
case UV_TTY:
|
||||
return uv_tty_write(loop, req, (uv_tty_t*) handle, bufs, bufcnt, cb);
|
||||
default:
|
||||
assert(0);
|
||||
uv_set_sys_error(loop, WSAEINVAL);
|
||||
|
||||
1492
src/win/tty.c
1492
src/win/tty.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user