33
44#ifdef _WIN32 // windows
55
6- #include < wchar.h>
76#include < windows.h>
87
98#else // not windows
2019#include < cassert>
2120#include < cstdint>
2221#include < iostream>
23- #include < ostream>
2422#include < sstream>
2523#include < string>
2624#include < utility> // for std::pair
@@ -60,7 +58,7 @@ namespace tui {
6058 exit (1 ); \
6159 } \
6260 DWORD mode; \
63- if (! GetConsoleMode(hStdin, &mode)) { \
61+ if (GetConsoleMode(hStdin, &mode) == 0 ) { \
6462 std::cerr << " error getting the console mode\n " ; \
6563 exit (1 ); \
6664 }
@@ -73,7 +71,7 @@ namespace tui {
7371 DWORD newMode = mode;
7472 newMode &= ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT);
7573
76- if (! SetConsoleMode (hStdin, newMode)) {
74+ if (SetConsoleMode (hStdin, newMode) == 0 ) {
7775 std::cerr << " error setting the console to raw mode\n " ;
7876 exit (1 );
7977 }
@@ -102,7 +100,7 @@ namespace tui {
102100
103101 // Restore original mode
104102 mode |= (ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT);
105- if (! SetConsoleMode (hStdin, mode)) {
103+ if (SetConsoleMode (hStdin, mode) == 0 ) {
106104 std::cerr << " error restoring the console mode\n " ;
107105 exit (1 );
108106 }
@@ -124,6 +122,27 @@ namespace tui {
124122
125123#undef win_setup
126124
125+ #ifdef _WIN32
126+ inline CONSOLE_SCREEN_BUFFER_INFO get_console_buf_info () {
127+ HANDLE console = nullptr ;
128+ CONSOLE_SCREEN_BUFFER_INFO info;
129+ // create a handle to the console screen
130+ console = CreateFileW (L" CONOUT$" , GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr ,
131+ OPEN_EXISTING, 0 , nullptr );
132+ if (console == INVALID_HANDLE_VALUE) {
133+ std::cerr << " couldn't get console handle\n " ;
134+ exit (1 );
135+ }
136+ // calculate the size of the console window
137+ if (GetConsoleScreenBufferInfo (console, &info) == 0 ) {
138+ std::cerr << " couldn't get console screen buffer info\n " ;
139+ exit (1 );
140+ }
141+ CloseHandle (console);
142+ return info;
143+ }
144+ #endif
145+
127146 namespace cursor {
128147// template for moving cursor
129148// moves cursor `n` times to `dir`
@@ -161,8 +180,17 @@ namespace tui {
161180 // tell the terminal to check where the cursor is
162181 csi_fn (query_position, " 6n" );
163182
183+ #ifdef _WIN32
184+ // returns: (rows;cols)
185+ inline std::pair<unsigned , unsigned > get_position () {
186+ auto info = get_console_buf_info ();
187+ auto rows = info.dwCursorPosition .X + 1 ;
188+ auto cols = info.dwCursorPosition .Y + 1 ;
189+ return {rows, cols};
190+ }
191+ #else
164192 // returns: (rows;cols)
165- // WARN : can be quite slow, don't use on eg. every screen update!
193+ // NOTE : can take a while (eg 16ms) on (relatively) slow terminals
166194 inline std::pair<unsigned , unsigned > get_position () {
167195 query_position ();
168196 std::flush (std::cout);
@@ -179,6 +207,8 @@ namespace tui {
179207
180208 return {rows, cols};
181209 }
210+ #endif
211+
182212 } // namespace cursor
183213
184214 namespace screen {
@@ -204,22 +234,9 @@ namespace tui {
204234 // returns: (rows;cols)/(y;x)
205235 inline std::pair<unsigned , unsigned > size () {
206236#ifdef _WIN32
207- HANDLE console;
208- CONSOLE_SCREEN_BUFFER_INFO info;
209- short rows;
210- short columns;
211- // create a handle to the console screen
212- console = CreateFileW (L" CONOUT$" , GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL ,
213- OPEN_EXISTING, 0 , NULL );
214- if (console == INVALID_HANDLE_VALUE)
215- return {0 , 0 };
216-
217- // calculate the size of the console window
218- if (GetConsoleScreenBufferInfo (console, &info) == 0 )
219- return {0 , 0 };
220- CloseHandle (console);
221- columns = info.srWindow .Right - info.srWindow .Left + 1 ;
222- rows = info.srWindow .Bottom - info.srWindow .Top + 1 ;
237+ auto info = get_console_buf_info ();
238+ int columns = info.srWindow .Right - info.srWindow .Left + 1 ;
239+ int rows = info.srWindow .Bottom - info.srWindow .Top + 1 ;
223240
224241 return {rows, columns};
225242#else
0 commit comments