2 /***************************************************************
3 ** I/O subsystem for PForth for WIN32 systems.
5 ** Use Windows Console so we can add the ANSI console commands needed to support HISTORY
8 ** Copyright 1994 3DO, Phil Burk, Larry Polansky, David Rosenboom
10 ** The pForth software code is dedicated to the public domain,
11 ** and any third party may reproduce, distribute and modify
12 ** the pForth software code or any derivative works thereof
13 ** without any compensation or license. The pForth software
14 ** code is provided on an "as is" basis without any warranty
15 ** of any kind, including, without limitation, the implied
16 ** warranties of merchantability and fitness for a particular
17 ** purpose and their equivalents under the laws of any jurisdiction.
19 ***************************************************************/
21 #include "../pf_all.h"
23 #if defined(WIN32) || defined(__NT__)
27 #define ASCII_ESCAPE (0x1B)
29 static HANDLE sConsoleHandle = INVALID_HANDLE_VALUE;
30 static int sIsConsoleValid = FALSE;
32 typedef enum ConsoleState_e
34 SDCONSOLE_STATE_IDLE = 0,
35 SDCONSOLE_STATE_GOT_ESCAPE,
36 SDCONSOLE_STATE_GOT_BRACKET
40 static int sConsoleState = SDCONSOLE_STATE_IDLE;
41 static int sParam1 = 0;
42 static CONSOLE_SCREEN_BUFFER_INFO sScreenInfo;
44 /******************************************************************/
45 static void sdConsoleEmit( char c )
47 /* Write a WCHAR in case we have compiled with Unicode support.
48 * Otherwise we will see '?' printed.*/
53 WriteConsoleW(sConsoleHandle, &wc, 1, &count, NULL );
57 /* This will get called if we are redirecting to a file.*/
58 WriteFile(sConsoleHandle, &c, 1, &count, NULL );
62 /******************************************************************/
63 static void sdClearScreen( void )
65 if( GetConsoleScreenBufferInfo( sConsoleHandle, &sScreenInfo ) )
71 XY.Y = sScreenInfo.srWindow.Top;
72 numNeeded = sScreenInfo.dwSize.X * (sScreenInfo.srWindow.Bottom - sScreenInfo.srWindow.Top + 1);
73 FillConsoleOutputCharacter(
74 sConsoleHandle, ' ', numNeeded, XY, &count );
75 SetConsoleCursorPosition( sConsoleHandle, XY );
79 /******************************************************************/
80 static void sdEraseEOL( void )
82 if( GetConsoleScreenBufferInfo( sConsoleHandle, &sScreenInfo ) )
87 savedXY.X = sScreenInfo.dwCursorPosition.X;
88 savedXY.Y = sScreenInfo.dwCursorPosition.Y;
89 numNeeded = sScreenInfo.dwSize.X - savedXY.X;
90 FillConsoleOutputCharacter(
91 sConsoleHandle, ' ', numNeeded, savedXY, &count );
95 /******************************************************************/
96 static void sdCursorBack( int dx )
98 if( GetConsoleScreenBufferInfo( sConsoleHandle, &sScreenInfo ) )
101 XY.X = sScreenInfo.dwCursorPosition.X;
102 XY.Y = sScreenInfo.dwCursorPosition.Y;
104 if( XY.X < 0 ) XY.X = 0;
105 SetConsoleCursorPosition( sConsoleHandle, XY );
108 /******************************************************************/
109 static void sdCursorForward( int dx )
111 if( GetConsoleScreenBufferInfo( sConsoleHandle, &sScreenInfo ) )
114 int width = sScreenInfo.dwSize.X;
115 XY.X = sScreenInfo.dwCursorPosition.X;
116 XY.Y = sScreenInfo.dwCursorPosition.Y;
118 if( XY.X > width ) XY.X = width;
119 SetConsoleCursorPosition( sConsoleHandle, XY );
123 /******************************************************************/
124 /* Use console mode I/O so that KEY and ?TERMINAL will work.
125 * Parse ANSI escape sequences and call the appropriate cursor
128 int sdTerminalOut( char c )
130 switch( sConsoleState )
132 case SDCONSOLE_STATE_IDLE:
136 sConsoleState = SDCONSOLE_STATE_GOT_ESCAPE;
143 case SDCONSOLE_STATE_GOT_ESCAPE:
147 sConsoleState = SDCONSOLE_STATE_GOT_BRACKET;
151 sConsoleState = SDCONSOLE_STATE_IDLE;
156 case SDCONSOLE_STATE_GOT_BRACKET:
157 if( (c >= '0') && (c <= '9') )
159 sParam1 = (sParam1 * 10) + (c - '0');
163 sConsoleState = SDCONSOLE_STATE_IDLE;
170 sdCursorBack( sParam1 );
174 sdCursorForward( sParam1 );
176 else if( (c == 'J') && (sParam1 == 2) )
186 /* Needed cuz _getch() does not echo. */
187 int sdTerminalEcho( char c )
189 sdConsoleEmit((char)(c));
193 int sdTerminalIn( void )
198 int sdQueryTerminal( void )
203 int sdTerminalFlush( void )
208 return fflush(PF_STDOUT);
212 void sdTerminalInit( void )
215 sConsoleHandle = GetStdHandle( STD_OUTPUT_HANDLE );
216 if( GetConsoleMode( sConsoleHandle, &mode ) )
218 /*printf("GetConsoleMode() mode is 0x%08X\n", mode );*/
219 sIsConsoleValid = TRUE;
223 /*printf("GetConsoleMode() failed\n", mode );*/
224 sIsConsoleValid = FALSE;
228 void sdTerminalTerm( void )