diff options
Diffstat (limited to 'osdep')
-rw-r--r-- | osdep/terminal-win.c | 50 | ||||
-rw-r--r-- | osdep/terminal.h | 3 | ||||
-rw-r--r-- | osdep/win32-console-wrapper.c | 4 |
3 files changed, 44 insertions, 13 deletions
diff --git a/osdep/terminal-win.c b/osdep/terminal-win.c index 678cedb775..03a1ba28c6 100644 --- a/osdep/terminal-win.c +++ b/osdep/terminal-win.c @@ -250,24 +250,48 @@ void mp_write_console_ansi(HANDLE wstream, char *buf) } } -int terminal_init(void) +static bool is_a_console(HANDLE h) +{ + return GetConsoleMode(h, &(DWORD){0}); +} + +static void reopen_console_handle(DWORD std, FILE *stream) +{ + HANDLE wstream = GetStdHandle(std); + if (is_a_console(wstream)) { + int fd = _open_osfhandle((intptr_t)wstream, _O_TEXT); + dup2(fd, fileno(stream)); + setvbuf(stream, NULL, _IONBF, 0); + } +} + +bool terminal_try_attach(void) { - if (AttachConsole(ATTACH_PARENT_PROCESS)) { - // We have been started by something with a console window. - // Redirect output streams to that console's low-level handles, - // so we can actually use WriteConsole later on. + // mpv.exe is a flagged as a GUI application, but it acts as a console + // application when started from the console wrapper (see + // osdep/win32-console-wrapper.c). The console wrapper sets + // _started_from_console=yes, so check that variable before trying to + // attach to the console. + wchar_t console_env[4] = { 0 }; + if (!GetEnvironmentVariableW(L"_started_from_console", console_env, 4)) + return false; + if (wcsncmp(console_env, L"yes", 4)) + return false; + SetEnvironmentVariableW(L"_started_from_console", NULL); - int hConHandle; + if (!AttachConsole(ATTACH_PARENT_PROCESS)) + return false; - hConHandle = _open_osfhandle((intptr_t)hSTDOUT, _O_TEXT); - *stdout = *_fdopen(hConHandle, "w"); - setvbuf(stdout, NULL, _IONBF, 0); + // We have a console window. Redirect output streams to that console's + // low-level handles, so we can actually use WriteConsole later on. + reopen_console_handle(STD_OUTPUT_HANDLE, stdout); + reopen_console_handle(STD_ERROR_HANDLE, stderr); - hConHandle = _open_osfhandle((intptr_t)hSTDERR, _O_TEXT); - *stderr = *_fdopen(hConHandle, "w"); - setvbuf(stderr, NULL, _IONBF, 0); - } + return true; +} +int terminal_init(void) +{ CONSOLE_SCREEN_BUFFER_INFO cinfo; DWORD cmode = 0; GetConsoleMode(hSTDOUT, &cmode); diff --git a/osdep/terminal.h b/osdep/terminal.h index fc98f0c469..89d4071d93 100644 --- a/osdep/terminal.h +++ b/osdep/terminal.h @@ -47,4 +47,7 @@ void terminal_get_size(int *w, int *h); // Windows only. void mp_write_console_ansi(void *wstream, char *buf); +/* Windows-only function to attach to the parent process's console */ +bool terminal_try_attach(void); + #endif /* MPLAYER_GETCH2_H */ diff --git a/osdep/win32-console-wrapper.c b/osdep/win32-console-wrapper.c index c8c297b482..8cebcf8c83 100644 --- a/osdep/win32-console-wrapper.c +++ b/osdep/win32-console-wrapper.c @@ -72,5 +72,9 @@ int wmain(int argc, wchar_t **argv, wchar_t **envp) GetModuleFileNameW(NULL, exe, MAX_PATH); wcscpy(wcsrchr(exe, '.') + 1, L"exe"); + // Set an environment variable so the child process can tell whether it + // was started from this wrapper and attach to the console accordingly + SetEnvironmentVariableW(L"_started_from_console", L"yes"); + return cr_runproc(exe, cmd); } |