diff options
author | erw7 <erw7.github@gmail.com> | 2019-11-09 15:46:12 +0900 |
---|---|---|
committer | Björn Linse <bjorn.linse@gmail.com> | 2020-01-17 11:36:28 +0100 |
commit | 5355cee77d7b3b62917036281406726832b6d7dc (patch) | |
tree | 17ce6d9f2a96613d2c6d12ec86475f40bf05b6f8 /src/nvim/os/pty_process_win.c | |
parent | 8fe0635e7338e32e8aedeb8f2e2c0f246876375c (diff) | |
download | rneovim-5355cee77d7b3b62917036281406726832b6d7dc.tar.gz rneovim-5355cee77d7b3b62917036281406726832b6d7dc.tar.bz2 rneovim-5355cee77d7b3b62917036281406726832b6d7dc.zip |
Change to use ConPTY, if available
Diffstat (limited to 'src/nvim/os/pty_process_win.c')
-rw-r--r-- | src/nvim/os/pty_process_win.c | 146 |
1 files changed, 97 insertions, 49 deletions
diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index 183219bd3e..f48fef76d3 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -12,6 +12,7 @@ #include "nvim/memory.h" #include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8 #include "nvim/os/pty_process_win.h" +#include "nvim/os/os_win_conpty.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/pty_process_win.c.generated.h" @@ -23,6 +24,11 @@ static void CALLBACK pty_process_finish1(void *context, BOOLEAN unused) PtyProcess *ptyproc = (PtyProcess *)context; Process *proc = (Process *)ptyproc; + if (ptyproc->type == PTY_TYPE_CONPTY + && ptyproc->pty_object.conpty_object != NULL) { + os_conpty_free(ptyproc->pty_object.conpty_object); + ptyproc->pty_object.conpty_object = NULL; + } uv_timer_init(&proc->loop->uv, &ptyproc->wait_eof_timer); ptyproc->wait_eof_timer.data = (void *)ptyproc; uv_timer_start(&ptyproc->wait_eof_timer, wait_eof_timer_cb, 200, 200); @@ -38,6 +44,7 @@ int pty_process_spawn(PtyProcess *ptyproc) winpty_config_t *cfg = NULL; winpty_spawn_config_t *spawncfg = NULL; winpty_t *winpty_object = NULL; + conpty_t *conpty_object = NULL; char *in_name = NULL; char *out_name = NULL; HANDLE process_handle = NULL; @@ -49,29 +56,40 @@ int pty_process_spawn(PtyProcess *ptyproc) assert(proc->err.closed); - cfg = winpty_config_new(WINPTY_FLAG_ALLOW_CURPROC_DESKTOP_CREATION, &err); - if (cfg == NULL) { - emsg = "winpty_config_new failed"; - goto cleanup; + int pty_type = *p_twt; + if (pty_type == 'c' && os_has_conpty_working()) { + if ((conpty_object = + os_conpty_init(&in_name, &out_name, + ptyproc->width, ptyproc->height)) != NULL) { + ptyproc->type = PTY_TYPE_CONPTY; + } } - winpty_config_set_initial_size(cfg, ptyproc->width, ptyproc->height); - winpty_object = winpty_open(cfg, &err); - if (winpty_object == NULL) { - emsg = "winpty_open failed"; - goto cleanup; - } + if (ptyproc->type == PTY_TYPE_WINPTY) { + cfg = winpty_config_new(WINPTY_FLAG_ALLOW_CURPROC_DESKTOP_CREATION, &err); + if (cfg == NULL) { + emsg = "winpty_config_new failed"; + goto cleanup; + } - status = utf16_to_utf8(winpty_conin_name(winpty_object), -1, &in_name); - if (status != 0) { - emsg = "utf16_to_utf8(winpty_conin_name) failed"; - goto cleanup; - } + winpty_config_set_initial_size(cfg, ptyproc->width, ptyproc->height); + winpty_object = winpty_open(cfg, &err); + if (winpty_object == NULL) { + emsg = "winpty_open failed"; + goto cleanup; + } - status = utf16_to_utf8(winpty_conout_name(winpty_object), -1, &out_name); - if (status != 0) { - emsg = "utf16_to_utf8(winpty_conout_name) failed"; - goto cleanup; + status = utf16_to_utf8(winpty_conin_name(winpty_object), -1, &in_name); + if (status != 0) { + emsg = "utf16_to_utf8(winpty_conin_name) failed"; + goto cleanup; + } + + status = utf16_to_utf8(winpty_conout_name(winpty_object), -1, &out_name); + if (status != 0) { + emsg = "utf16_to_utf8(winpty_conout_name) failed"; + goto cleanup; + } } if (!proc->in.closed) { @@ -107,32 +125,45 @@ int pty_process_spawn(PtyProcess *ptyproc) goto cleanup; } - spawncfg = winpty_spawn_config_new( - WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN, - NULL, // Optional application name - cmd_line, - cwd, - NULL, // Optional environment variables - &err); - if (spawncfg == NULL) { - emsg = "winpty_spawn_config_new failed"; - goto cleanup; - } + if (ptyproc->type == PTY_TYPE_CONPTY) { + if (!os_conpty_spawn(conpty_object, + &process_handle, + NULL, + cmd_line, + cwd, + NULL)) { + emsg = "os_conpty_spawn failed"; + status = (int)GetLastError(); + goto cleanup; + } + } else { + spawncfg = winpty_spawn_config_new( + WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN, + NULL, // Optional application name + cmd_line, + cwd, + NULL, // Optional environment variables + &err); + if (spawncfg == NULL) { + emsg = "winpty_spawn_config_new failed"; + goto cleanup; + } - DWORD win_err = 0; - if (!winpty_spawn(winpty_object, - spawncfg, - &process_handle, - NULL, // Optional thread handle - &win_err, - &err)) { - if (win_err) { - status = (int)win_err; - emsg = "failed to spawn process"; - } else { - emsg = "winpty_spawn failed"; + DWORD win_err = 0; + if (!winpty_spawn(winpty_object, + spawncfg, + &process_handle, + NULL, // Optional thread handle + &win_err, + &err)) { + if (win_err) { + status = (int)win_err; + emsg = "failed to spawn process"; + } else { + emsg = "winpty_spawn failed"; + } + goto cleanup; } - goto cleanup; } proc->pid = (int)GetProcessId(process_handle); @@ -152,9 +183,14 @@ int pty_process_spawn(PtyProcess *ptyproc) uv_run(&proc->loop->uv, UV_RUN_ONCE); } - ptyproc->winpty_object = winpty_object; + if (ptyproc->type == PTY_TYPE_CONPTY) { + ptyproc->pty_object.conpty_object = conpty_object; + } else { + ptyproc->pty_object.winpty_object = winpty_object; + } ptyproc->process_handle = process_handle; winpty_object = NULL; + conpty_object = NULL; process_handle = NULL; cleanup: @@ -171,6 +207,7 @@ cleanup: winpty_config_free(cfg); winpty_spawn_config_free(spawncfg); winpty_free(winpty_object); + os_conpty_free(conpty_object); xfree(in_name); xfree(out_name); if (process_handle != NULL) { @@ -192,8 +229,18 @@ void pty_process_resize(PtyProcess *ptyproc, uint16_t width, uint16_t height) FUNC_ATTR_NONNULL_ALL { - if (ptyproc->winpty_object != NULL) { - winpty_set_size(ptyproc->winpty_object, width, height, NULL); + if (ptyproc->type == PTY_TYPE_CONPTY + && ptyproc->pty_object.conpty_object != NULL) { + assert(width <= SHRT_MAX); + assert(height <= SHRT_MAX); + COORD size = { (int16_t)width, (int16_t)height }; + if (pResizePseudoConsole( + ptyproc->pty_object.conpty_object->pty, size) != S_OK) { + ELOG("ResizePseudoConsoel failed: error code: %d", + os_translate_sys_error((int)GetLastError())); + } + } else if (ptyproc->pty_object.winpty_object != NULL) { + winpty_set_size(ptyproc->pty_object.winpty_object, width, height, NULL); } } @@ -212,9 +259,10 @@ void pty_process_close(PtyProcess *ptyproc) void pty_process_close_master(PtyProcess *ptyproc) FUNC_ATTR_NONNULL_ALL { - if (ptyproc->winpty_object != NULL) { - winpty_free(ptyproc->winpty_object); - ptyproc->winpty_object = NULL; + if (ptyproc->type == PTY_TYPE_WINPTY + && ptyproc->pty_object.winpty_object != NULL) { + winpty_free(ptyproc->pty_object.winpty_object); + ptyproc->pty_object.winpty_object = NULL; } } |