summaryrefslogtreecommitdiff
path: root/tier0/win32consoleio.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tier0/win32consoleio.cpp')
-rw-r--r--tier0/win32consoleio.cpp91
1 files changed, 91 insertions, 0 deletions
diff --git a/tier0/win32consoleio.cpp b/tier0/win32consoleio.cpp
new file mode 100644
index 0000000..b83bc13
--- /dev/null
+++ b/tier0/win32consoleio.cpp
@@ -0,0 +1,91 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Attaches a console for I/O to a Win32 GUI application in a
+// reasonably smart fashion
+//
+//=============================================================================
+
+#include "pch_tier0.h"
+
+#if defined( _WIN32 )
+
+#include <windows.h>
+#include <io.h>
+#include <fcntl.h>
+
+#include <iostream>
+
+#endif // defined( _WIN32 )
+
+//-----------------------------------------------------------------------------
+//
+// Attach a console to a Win32 GUI process and setup stdin, stdout & stderr
+// along with the std::iostream (cout, cin, cerr) equivalents to read and
+// write to and from that console
+//
+// 1. Ensure the handle associated with stdio is FILE_TYPE_UNKNOWN
+// if it's anything else just return false. This supports cygwin
+// style command shells like rxvt which setup pipes to processes
+// they spawn
+//
+// 2. See if the Win32 function call AttachConsole exists in kernel32
+// It's a Windows 2000 and above call. If it does, call it and see
+// if it succeeds in attaching to the console of the parent process.
+// If that succeeds, return false (for no new console allocated).
+// This supports someone typing the command from a normal windows
+// command window and having the output go to the parent window.
+// It's a little funny because a GUI app detaches so the command
+// prompt gets intermingled with output from this process
+//
+// 3. If thigns get to here call AllocConsole which will pop open
+// a new window and allow output to go to that window. The
+// window will disappear when the process exists so if it's used
+// for something like a help message then do something like getchar()
+// from stdin to wait for a keypress. if AllocConsole is called
+// true is returned.
+//
+// Return: true if AllocConsole() was used to pop open a new windows console
+//
+//-----------------------------------------------------------------------------
+
+
+bool SetupWin32ConsoleIO()
+{
+#if defined( _WIN32 )
+ // Only useful on Windows platforms
+
+ bool newConsole( false );
+
+ if ( GetFileType( GetStdHandle( STD_OUTPUT_HANDLE ) ) == FILE_TYPE_UNKNOWN )
+ {
+
+ HINSTANCE hInst = ::LoadLibrary( "kernel32.dll" );
+ typedef BOOL ( WINAPI * pAttachConsole_t )( DWORD );
+ pAttachConsole_t pAttachConsole( ( BOOL ( _stdcall * )( DWORD ) )GetProcAddress( hInst, "AttachConsole" ) );
+
+ if ( !( pAttachConsole && (*pAttachConsole)( ( DWORD ) - 1 ) ) )
+ {
+ newConsole = true;
+ AllocConsole();
+ }
+
+ *stdout = *_fdopen( _open_osfhandle( reinterpret_cast< intptr_t >( GetStdHandle( STD_OUTPUT_HANDLE ) ), _O_TEXT ), "w" );
+ setvbuf( stdout, NULL, _IONBF, 0 );
+
+ *stdin = *_fdopen( _open_osfhandle( reinterpret_cast< intptr_t >( GetStdHandle( STD_INPUT_HANDLE ) ), _O_TEXT ), "r" );
+ setvbuf( stdin, NULL, _IONBF, 0 );
+
+ *stderr = *_fdopen( _open_osfhandle( reinterpret_cast< intptr_t >( GetStdHandle( STD_ERROR_HANDLE ) ), _O_TEXT ), "w" );
+ setvbuf( stdout, NULL, _IONBF, 0 );
+
+ std::ios_base::sync_with_stdio();
+ }
+
+ return newConsole;
+
+#else // defined( _WIN32 )
+
+ return false;
+
+#endif // defined( _WIN32 )
+} \ No newline at end of file