Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

161 lines
6.1 KiB

  1. //======= Copyright � 1996-2006, Valve Corporation, All rights reserved. ======
  2. //
  3. // Purpose: Win32 Console API helpers
  4. //
  5. //=============================================================================
  6. #include "pch_tier0.h"
  7. #include "win32consoleio.h"
  8. #if defined( _WIN32 )
  9. #define WIN32_LEAN_AND_MEAN
  10. #include <windows.h>
  11. #include <io.h>
  12. #include <fcntl.h>
  13. #include <iostream>
  14. #endif // defined( _WIN32 )
  15. // NOTE: This has to be the last file included!
  16. #include "tier0/memdbgon.h"
  17. //-----------------------------------------------------------------------------
  18. //
  19. // Attach a console to a Win32 GUI process and setup stdin, stdout & stderr
  20. // along with the std::iostream (cout, cin, cerr) equivalents to read and
  21. // write to and from that console
  22. //
  23. // 1. Ensure the handle associated with stdio is FILE_TYPE_UNKNOWN
  24. // if it's anything else just return false. This supports cygwin
  25. // style command shells like rxvt which setup pipes to processes
  26. // they spawn
  27. //
  28. // 2. See if the Win32 function call AttachConsole exists in kernel32
  29. // It's a Windows 2000 and above call. If it does, call it and see
  30. // if it succeeds in attaching to the console of the parent process.
  31. // If that succeeds, return false (for no new console allocated).
  32. // This supports someone typing the command from a normal windows
  33. // command window and having the output go to the parent window.
  34. // It's a little funny because a GUI app detaches so the command
  35. // prompt gets intermingled with output from this process
  36. //
  37. // 3. If things get to here call AllocConsole which will pop open
  38. // a new window and allow output to go to that window. The
  39. // window will disappear when the process exists so if it's used
  40. // for something like a help message then do something like getchar()
  41. // from stdin to wait for a keypress. if AllocConsole is called
  42. // true is returned.
  43. //
  44. // Return: true if AllocConsole() was used to pop open a new windows console
  45. //
  46. //-----------------------------------------------------------------------------
  47. bool SetupWin32ConsoleIO()
  48. {
  49. #if defined( _WIN32 )
  50. // Only useful on Windows platforms
  51. bool newConsole( false );
  52. if ( GetFileType( GetStdHandle( STD_OUTPUT_HANDLE ) ) == FILE_TYPE_UNKNOWN )
  53. {
  54. HINSTANCE hInst = ::LoadLibrary( "kernel32.dll" );
  55. typedef BOOL ( WINAPI * pAttachConsole_t )( DWORD );
  56. pAttachConsole_t pAttachConsole( ( BOOL ( _stdcall * )( DWORD ) )GetProcAddress( hInst, "AttachConsole" ) );
  57. if ( !( pAttachConsole && (*pAttachConsole)( ( DWORD ) - 1 ) ) )
  58. {
  59. newConsole = true;
  60. AllocConsole();
  61. }
  62. *stdout = *_fdopen( _open_osfhandle( reinterpret_cast< intp >( GetStdHandle( STD_OUTPUT_HANDLE ) ), _O_TEXT ), "w" );
  63. setvbuf( stdout, NULL, _IONBF, 0 );
  64. *stdin = *_fdopen( _open_osfhandle( reinterpret_cast< intp >( GetStdHandle( STD_INPUT_HANDLE ) ), _O_TEXT ), "r" );
  65. setvbuf( stdin, NULL, _IONBF, 0 );
  66. *stderr = *_fdopen( _open_osfhandle( reinterpret_cast< intp >( GetStdHandle( STD_ERROR_HANDLE ) ), _O_TEXT ), "w" );
  67. setvbuf( stdout, NULL, _IONBF, 0 );
  68. std::ios_base::sync_with_stdio();
  69. }
  70. return newConsole;
  71. #else // defined( _WIN32 )
  72. return false;
  73. #endif // defined( _WIN32 )
  74. }
  75. //-----------------------------------------------------------------------------
  76. // Win32 Console Color API Helpers, originally from cmdlib.
  77. // Retrieves the current console color attributes.
  78. //-----------------------------------------------------------------------------
  79. void InitWin32ConsoleColorContext( Win32ConsoleColorContext_t *pContext )
  80. {
  81. #if PLATFORM_WINDOWS_PC
  82. // Get the old background attributes.
  83. CONSOLE_SCREEN_BUFFER_INFO oldInfo;
  84. GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &oldInfo );
  85. pContext->m_InitialColor = pContext->m_LastColor = oldInfo.wAttributes & (FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY);
  86. pContext->m_BackgroundFlags = oldInfo.wAttributes & (BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE|BACKGROUND_INTENSITY);
  87. pContext->m_BadColor = 0;
  88. if (pContext->m_BackgroundFlags & BACKGROUND_RED)
  89. pContext->m_BadColor |= FOREGROUND_RED;
  90. if (pContext->m_BackgroundFlags & BACKGROUND_GREEN)
  91. pContext->m_BadColor |= FOREGROUND_GREEN;
  92. if (pContext->m_BackgroundFlags & BACKGROUND_BLUE)
  93. pContext->m_BadColor |= FOREGROUND_BLUE;
  94. if (pContext->m_BackgroundFlags & BACKGROUND_INTENSITY)
  95. pContext->m_BadColor |= FOREGROUND_INTENSITY;
  96. #else
  97. pContext->m_InitialColor = 0;
  98. #endif
  99. }
  100. //-----------------------------------------------------------------------------
  101. // Sets the active console foreground color. This function is smart enough to
  102. // avoid setting the color to something that would be unreadable given
  103. // the user's potentially customized background color. It leaves the
  104. // background color unchanged.
  105. // Returns: The console's previous foreground color.
  106. //-----------------------------------------------------------------------------
  107. uint16 SetWin32ConsoleColor( Win32ConsoleColorContext_t *pContext, int nRed, int nGreen, int nBlue, int nIntensity )
  108. {
  109. #if PLATFORM_WINDOWS_PC
  110. uint16 ret = pContext->m_LastColor;
  111. pContext->m_LastColor = 0;
  112. if ( nRed ) pContext->m_LastColor |= FOREGROUND_RED;
  113. if ( nGreen ) pContext->m_LastColor |= FOREGROUND_GREEN;
  114. if ( nBlue ) pContext->m_LastColor |= FOREGROUND_BLUE;
  115. if ( nIntensity ) pContext->m_LastColor |= FOREGROUND_INTENSITY;
  116. // Just use the initial color if there's a match...
  117. if ( pContext->m_LastColor == pContext->m_BadColor )
  118. pContext->m_LastColor = pContext->m_InitialColor;
  119. SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), pContext->m_LastColor | pContext->m_BackgroundFlags );
  120. return ret;
  121. #else
  122. return 0;
  123. #endif
  124. }
  125. //-----------------------------------------------------------------------------
  126. // Restore's the active foreground console color, without distributing the current
  127. // background color.
  128. //-----------------------------------------------------------------------------
  129. void RestoreWin32ConsoleColor( Win32ConsoleColorContext_t *pContext, uint16 prevColor )
  130. {
  131. #if PLATFORM_WINDOWS_PC
  132. SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), prevColor | pContext->m_BackgroundFlags );
  133. pContext->m_LastColor = prevColor;
  134. #endif
  135. }