1 #ifdef _WIN32
2 
3 #include <iostream>
4 
5 #include "windows.hxx"
6 #include "conversion.hxx"
7 #include "terminal.hxx"
8 
9 using namespace std;
10 
11 namespace replxx {
12 
13 WinAttributes WIN_ATTR;
14 
15 template<typename T>
HandleEsc(HANDLE out_,T * p,T * end)16 T* HandleEsc(HANDLE out_, T* p, T* end) {
17 	if (*p == '[') {
18 		int code = 0;
19 
20 		int thisBackground( WIN_ATTR._defaultBackground );
21 		for (++p; p < end; ++p) {
22 			char32_t c = *p;
23 
24 			if ('0' <= c && c <= '9') {
25 				code = code * 10 + (c - '0');
26 			} else if (c == 'm' || c == ';') {
27 				switch (code) {
28 					case 0:
29 						WIN_ATTR._consoleAttribute = WIN_ATTR._defaultAttribute;
30 						WIN_ATTR._consoleColor = WIN_ATTR._defaultColor | thisBackground;
31 						break;
32 					case 1:	// BOLD
33 					case 5:	// BLINK
34 						WIN_ATTR._consoleAttribute = (WIN_ATTR._defaultAttribute ^ FOREGROUND_INTENSITY) & INTENSITY;
35 						break;
36 					case 22:
37 						WIN_ATTR._consoleAttribute = WIN_ATTR._defaultAttribute;
38 						break;
39 					case 30:
40 					case 90:
41 						WIN_ATTR._consoleColor = thisBackground;
42 						break;
43 					case 31:
44 					case 91:
45 						WIN_ATTR._consoleColor = FOREGROUND_RED | thisBackground;
46 						break;
47 					case 32:
48 					case 92:
49 						WIN_ATTR._consoleColor = FOREGROUND_GREEN | thisBackground;
50 						break;
51 					case 33:
52 					case 93:
53 						WIN_ATTR._consoleColor = FOREGROUND_RED | FOREGROUND_GREEN | thisBackground;
54 						break;
55 					case 34:
56 					case 94:
57 						WIN_ATTR._consoleColor = FOREGROUND_BLUE | thisBackground;
58 						break;
59 					case 35:
60 					case 95:
61 						WIN_ATTR._consoleColor = FOREGROUND_BLUE | FOREGROUND_RED | thisBackground;
62 						break;
63 					case 36:
64 					case 96:
65 						WIN_ATTR._consoleColor = FOREGROUND_BLUE | FOREGROUND_GREEN | thisBackground;
66 						break;
67 					case 37:
68 					case 97:
69 						WIN_ATTR._consoleColor = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | thisBackground;
70 						break;
71 					case 101:
72 						thisBackground = BACKGROUND_RED;
73 						break;
74 				}
75 
76 				if ( ( code >= 90 ) && ( code <= 97 ) ) {
77 					WIN_ATTR._consoleAttribute = (WIN_ATTR._defaultAttribute ^ FOREGROUND_INTENSITY) & INTENSITY;
78 				}
79 
80 				code = 0;
81 			}
82 
83 			if (*p == 'm') {
84 				++p;
85 				break;
86 			}
87 		}
88 	} else {
89 		++p;
90 	}
91 
92 	SetConsoleTextAttribute(
93 		out_,
94 		WIN_ATTR._consoleAttribute | WIN_ATTR._consoleColor
95 	);
96 
97 	return p;
98 }
99 
win_write(HANDLE out_,bool autoEscape_,char const * str_,int size_)100 int win_write( HANDLE out_, bool autoEscape_, char const* str_, int size_ ) {
101 	int count( 0 );
102 	if ( tty::out ) {
103 		DWORD nWritten( 0 );
104 		if ( autoEscape_ ) {
105 			WriteConsoleA( out_, str_, size_, &nWritten, nullptr );
106 			count = nWritten;
107 		} else {
108 			char const* s( str_ );
109 			char const* e( str_ + size_ );
110 			while ( str_ < e ) {
111 				if ( *str_ == 27 ) {
112 					if ( s < str_ ) {
113 						int toWrite( static_cast<int>( str_ - s ) );
114 						WriteConsoleA( out_, s, static_cast<DWORD>( toWrite ), &nWritten, nullptr );
115 						count += nWritten;
116 						if ( nWritten != toWrite ) {
117 							s = str_ = nullptr;
118 							break;
119 						}
120 					}
121 					s = HandleEsc( out_, str_ + 1, e );
122 					int escaped( static_cast<int>( s - str_ ) );
123 					count += escaped;
124 					str_ = s;
125 				} else {
126 					++ str_;
127 				}
128 			}
129 
130 			if ( s < str_ ) {
131 				WriteConsoleA( out_, s, static_cast<DWORD>( str_ - s ), &nWritten, nullptr );
132 				count += nWritten;
133 			}
134 		}
135 	} else {
136 		count = _write( 1, str_, size_ );
137 	}
138 	return ( count );
139 }
140 
141 }
142 
143 #endif
144 
145