summaryrefslogtreecommitdiffstats
path: root/contrib/replxx/src/windows.cxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--contrib/replxx/src/windows.cxx144
1 files changed, 144 insertions, 0 deletions
diff --git a/contrib/replxx/src/windows.cxx b/contrib/replxx/src/windows.cxx
new file mode 100644
index 0000000..715292c
--- /dev/null
+++ b/contrib/replxx/src/windows.cxx
@@ -0,0 +1,144 @@
+#ifdef _WIN32
+
+#include <iostream>
+
+#include "windows.hxx"
+#include "conversion.hxx"
+#include "terminal.hxx"
+
+using namespace std;
+
+namespace replxx {
+
+WinAttributes WIN_ATTR;
+
+template<typename T>
+T* HandleEsc(HANDLE out_, T* p, T* end) {
+ if (*p == '[') {
+ int code = 0;
+
+ int thisBackground( WIN_ATTR._defaultBackground );
+ for (++p; p < end; ++p) {
+ char32_t c = *p;
+
+ if ('0' <= c && c <= '9') {
+ code = code * 10 + (c - '0');
+ } else if (c == 'm' || c == ';') {
+ switch (code) {
+ case 0:
+ WIN_ATTR._consoleAttribute = WIN_ATTR._defaultAttribute;
+ WIN_ATTR._consoleColor = WIN_ATTR._defaultColor | thisBackground;
+ break;
+ case 1: // BOLD
+ case 5: // BLINK
+ WIN_ATTR._consoleAttribute = (WIN_ATTR._defaultAttribute ^ FOREGROUND_INTENSITY) & INTENSITY;
+ break;
+ case 22:
+ WIN_ATTR._consoleAttribute = WIN_ATTR._defaultAttribute;
+ break;
+ case 30:
+ case 90:
+ WIN_ATTR._consoleColor = thisBackground;
+ break;
+ case 31:
+ case 91:
+ WIN_ATTR._consoleColor = FOREGROUND_RED | thisBackground;
+ break;
+ case 32:
+ case 92:
+ WIN_ATTR._consoleColor = FOREGROUND_GREEN | thisBackground;
+ break;
+ case 33:
+ case 93:
+ WIN_ATTR._consoleColor = FOREGROUND_RED | FOREGROUND_GREEN | thisBackground;
+ break;
+ case 34:
+ case 94:
+ WIN_ATTR._consoleColor = FOREGROUND_BLUE | thisBackground;
+ break;
+ case 35:
+ case 95:
+ WIN_ATTR._consoleColor = FOREGROUND_BLUE | FOREGROUND_RED | thisBackground;
+ break;
+ case 36:
+ case 96:
+ WIN_ATTR._consoleColor = FOREGROUND_BLUE | FOREGROUND_GREEN | thisBackground;
+ break;
+ case 37:
+ case 97:
+ WIN_ATTR._consoleColor = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | thisBackground;
+ break;
+ case 101:
+ thisBackground = BACKGROUND_RED;
+ break;
+ }
+
+ if ( ( code >= 90 ) && ( code <= 97 ) ) {
+ WIN_ATTR._consoleAttribute = (WIN_ATTR._defaultAttribute ^ FOREGROUND_INTENSITY) & INTENSITY;
+ }
+
+ code = 0;
+ }
+
+ if (*p == 'm') {
+ ++p;
+ break;
+ }
+ }
+ } else {
+ ++p;
+ }
+
+ SetConsoleTextAttribute(
+ out_,
+ WIN_ATTR._consoleAttribute | WIN_ATTR._consoleColor
+ );
+
+ return p;
+}
+
+int win_write( HANDLE out_, bool autoEscape_, char const* str_, int size_ ) {
+ int count( 0 );
+ if ( tty::out ) {
+ DWORD nWritten( 0 );
+ if ( autoEscape_ ) {
+ WriteConsoleA( out_, str_, size_, &nWritten, nullptr );
+ count = nWritten;
+ } else {
+ char const* s( str_ );
+ char const* e( str_ + size_ );
+ while ( str_ < e ) {
+ if ( *str_ == 27 ) {
+ if ( s < str_ ) {
+ int toWrite( static_cast<int>( str_ - s ) );
+ WriteConsoleA( out_, s, static_cast<DWORD>( toWrite ), &nWritten, nullptr );
+ count += nWritten;
+ if ( nWritten != toWrite ) {
+ s = str_ = nullptr;
+ break;
+ }
+ }
+ s = HandleEsc( out_, str_ + 1, e );
+ int escaped( static_cast<int>( s - str_ ) );
+ count += escaped;
+ str_ = s;
+ } else {
+ ++ str_;
+ }
+ }
+
+ if ( s < str_ ) {
+ WriteConsoleA( out_, s, static_cast<DWORD>( str_ - s ), &nWritten, nullptr );
+ count += nWritten;
+ }
+ }
+ } else {
+ count = _write( 1, str_, size_ );
+ }
+ return ( count );
+}
+
+}
+
+#endif
+