11#ifdef _WIN32
2+ #include " cpp-terminal/platforms/file.hpp"
3+
24 #include < windows.h>
3- typedef NTSTATUS (WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
45#endif
56
67#include " cpp-terminal/platforms/env.hpp"
78#include " cpp-terminal/terminfo.hpp"
89
910#include < string>
1011
11- #ifdef _WIN32
12+ #if defined( _WIN32)
1213bool WindowsVersionGreater (const DWORD& major, const DWORD& minor, const DWORD& patch)
1314{
14- RtlGetVersionPtr fn = {reinterpret_cast <RtlGetVersionPtr>(GetProcAddress (GetModuleHandle (TEXT (" ntdll.dll" )), " RtlGetVersion" ))};
15- if (fn != nullptr )
15+ #if defined(_MSC_VER)
16+ #pragma warning(push)
17+ #pragma warning(disable : 4191)
18+ #endif
19+ NTSTATUS (WINAPI * getVersion)(PRTL_OSVERSIONINFOW) = (reinterpret_cast <NTSTATUS (WINAPI*)(PRTL_OSVERSIONINFOW)>(GetProcAddress (GetModuleHandle (TEXT (" ntdll.dll" )), " RtlGetVersion" )));
20+ #if defined(_MSC_VER)
21+ #pragma warning(pop)
22+ #endif
23+ if (getVersion != nullptr )
1624 {
1725 RTL_OSVERSIONINFOW rovi;
1826 rovi.dwOSVersionInfoSize = sizeof (rovi);
19- if (fn (&rovi) == 0 )
27+ if (getVersion (&rovi) == 0 )
2028 {
2129 if (rovi.dwMajorVersion > major || (rovi.dwMajorVersion == major && (rovi.dwMinorVersion > minor || (rovi.dwMinorVersion == minor && rovi.dwBuildNumber >= patch)))) return true ;
2230 else
@@ -27,7 +35,35 @@ bool WindowsVersionGreater(const DWORD& major, const DWORD& minor, const DWORD&
2735}
2836#endif
2937
30- Term::Terminfo::ColorMode Term::Terminfo::m_colorMode{Term::Terminfo::ColorMode::Unset};
38+ void Term::Terminfo::setLegacy ()
39+ {
40+ #if defined(_WIN32)
41+ #ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
42+ #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
43+ #endif
44+ if (!hasANSIEscapeCode ()) m_legacy = true ;
45+ else
46+ {
47+ DWORD dwOriginalOutMode{0 };
48+ Term::Private::m_fileInitializer.initialize (); // Just in case
49+ GetConsoleMode (Private::std_cout.getHandler (), &dwOriginalOutMode);
50+ if (!SetConsoleMode (Private::std_cout.getHandler (), dwOriginalOutMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING)) m_legacy = true ;
51+ else
52+ {
53+ SetConsoleMode (Private::std_cout.getHandler (), dwOriginalOutMode);
54+ m_legacy = false ;
55+ }
56+ }
57+ #else
58+ m_legacy = false ;
59+ #endif
60+ }
61+
62+ Term::Terminfo::ColorMode Term::Terminfo::getColorMode () { return m_colorMode; }
63+
64+ bool Term::Terminfo::isLegacy () const { return m_legacy; }
65+
66+ Term::Terminfo::ColorMode Term::Terminfo::m_colorMode{ColorMode::Unset};
3167
3268Term::Terminfo::Terminfo ()
3369{
@@ -37,30 +73,33 @@ Term::Terminfo::Terminfo()
3773 if (Private::getenv (" ANSICON" ).first ) m_terminalName = " ansicon" ;
3874 m_terminalVersion = Private::getenv (" TERM_PROGRAM_VERSION" ).second ;
3975 setANSIEscapeCode ();
76+ setLegacy ();
4077 setColorMode ();
4178}
4279
43- bool Term::Terminfo::hasANSIEscapeCode () { return m_ANSIEscapeCode; }
80+ bool Term::Terminfo::hasANSIEscapeCode () const { return m_ANSIEscapeCode; }
4481
4582void Term::Terminfo::setColorMode ()
4683{
47- std::string colorterm = Private::getenv (" COLORTERM" ).second ;
48- if (colorterm == " truecolor" || colorterm == " 24bit" ) m_colorMode = Term::Terminfo::ColorMode::Bit24;
49- else
50- m_colorMode = Term::Terminfo::ColorMode::Bit8;
5184 if (m_terminalName == " Apple_Terminal" ) m_colorMode = Term::Terminfo::ColorMode::Bit8;
5285 else if (m_terminalName == " JetBrains-JediTerm" )
5386 m_colorMode = Term::Terminfo::ColorMode::Bit24;
5487 else if (m_terminalName == " vscode" )
5588 m_colorMode = Term::Terminfo::ColorMode::Bit24;
56- #ifdef _WIN32
57- else if (WindowsVersionGreater (10 , 0 , 10586 ))
58- m_colorMode = Term::Terminfo::ColorMode::Bit24;
5989 else if (m_terminalName == " ansicon" )
6090 m_colorMode = Term::Terminfo::ColorMode::Bit4;
61- else
91+ else if (m_term == " linux" )
92+ m_colorMode = Term::Terminfo::ColorMode::Bit4;
93+ #if defined(_WIN32)
94+ else if (WindowsVersionGreater (10 , 0 , 10586 ) && !isLegacy ())
95+ m_colorMode = Term::Terminfo::ColorMode::Bit24;
96+ else if (isLegacy ())
6297 m_colorMode = Term::Terminfo::ColorMode::Bit4;
6398#endif
99+ std::string colorterm = Private::getenv (" COLORTERM" ).second ;
100+ if ((colorterm == " truecolor" || colorterm == " 24bit" ) && m_colorMode != ColorMode::Unset) m_colorMode = Term::Terminfo::ColorMode::Bit24;
101+ else
102+ m_colorMode = Term::Terminfo::ColorMode::Bit4;
64103}
65104
66105void Term::Terminfo::setANSIEscapeCode ()
0 commit comments