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 ** Permission to use, copy, modify, and/or distribute this
11 ** software for any purpose with or without fee is hereby granted.
13 ** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
14 ** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
15 ** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
16 ** THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
17 ** CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
18 ** FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19 ** CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20 ** OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 ***************************************************************/
24 #include "../pf_all.h"
26 #if defined(WIN32) || defined(__NT__)
30 #define ASCII_ESCAPE (0x1B)
32 static HANDLE sConsoleHandle = INVALID_HANDLE_VALUE;
33 static int sIsConsoleValid = FALSE;
35 typedef enum ConsoleState_e
37 SDCONSOLE_STATE_IDLE = 0,
38 SDCONSOLE_STATE_GOT_ESCAPE,
39 SDCONSOLE_STATE_GOT_BRACKET
43 static int sConsoleState = SDCONSOLE_STATE_IDLE;
44 static int sParam1 = 0;
45 static CONSOLE_SCREEN_BUFFER_INFO sScreenInfo;
47 /******************************************************************/
48 static void sdConsoleEmit( char c )
50 /* Write a WCHAR in case we have compiled with Unicode support.
51 * Otherwise we will see '?' printed.*/
56 WriteConsoleW(sConsoleHandle, &wc, 1, &count, NULL );
60 /* This will get called if we are redirecting to a file.*/
61 WriteFile(sConsoleHandle, &c, 1, &count, NULL );
65 /******************************************************************/
66 static void sdClearScreen( void )
68 if( GetConsoleScreenBufferInfo( sConsoleHandle, &sScreenInfo ) )
74 XY.Y = sScreenInfo.srWindow.Top;
75 numNeeded = sScreenInfo.dwSize.X * (sScreenInfo.srWindow.Bottom - sScreenInfo.srWindow.Top + 1);
76 FillConsoleOutputCharacter(
77 sConsoleHandle, ' ', numNeeded, XY, &count );
78 SetConsoleCursorPosition( sConsoleHandle, XY );
82 /******************************************************************/
83 static void sdEraseEOL( void )
85 if( GetConsoleScreenBufferInfo( sConsoleHandle, &sScreenInfo ) )
90 savedXY.X = sScreenInfo.dwCursorPosition.X;
91 savedXY.Y = sScreenInfo.dwCursorPosition.Y;
92 numNeeded = sScreenInfo.dwSize.X - savedXY.X;
93 FillConsoleOutputCharacter(
94 sConsoleHandle, ' ', numNeeded, savedXY, &count );
98 /******************************************************************/
99 static void sdCursorBack( int dx )
101 if( GetConsoleScreenBufferInfo( sConsoleHandle, &sScreenInfo ) )
104 XY.X = sScreenInfo.dwCursorPosition.X;
105 XY.Y = sScreenInfo.dwCursorPosition.Y;
107 if( XY.X < 0 ) XY.X = 0;
108 SetConsoleCursorPosition( sConsoleHandle, XY );
111 /******************************************************************/
112 static void sdCursorForward( int dx )
114 if( GetConsoleScreenBufferInfo( sConsoleHandle, &sScreenInfo ) )
117 int width = sScreenInfo.dwSize.X;
118 XY.X = sScreenInfo.dwCursorPosition.X;
119 XY.Y = sScreenInfo.dwCursorPosition.Y;
121 if( XY.X > width ) XY.X = width;
122 SetConsoleCursorPosition( sConsoleHandle, XY );
126 /******************************************************************/
127 /* Use console mode I/O so that KEY and ?TERMINAL will work.
128 * Parse ANSI escape sequences and call the appropriate cursor
131 int sdTerminalOut( char c )
133 switch( sConsoleState )
135 case SDCONSOLE_STATE_IDLE:
139 sConsoleState = SDCONSOLE_STATE_GOT_ESCAPE;
146 case SDCONSOLE_STATE_GOT_ESCAPE:
150 sConsoleState = SDCONSOLE_STATE_GOT_BRACKET;
154 sConsoleState = SDCONSOLE_STATE_IDLE;
159 case SDCONSOLE_STATE_GOT_BRACKET:
160 if( (c >= '0') && (c <= '9') )
162 sParam1 = (sParam1 * 10) + (c - '0');
166 sConsoleState = SDCONSOLE_STATE_IDLE;
173 sdCursorBack( sParam1 );
177 sdCursorForward( sParam1 );
179 else if( (c == 'J') && (sParam1 == 2) )
189 /* Needed cuz _getch() does not echo. */
190 int sdTerminalEcho( char c )
192 sdConsoleEmit((char)(c));
196 int sdTerminalIn( void )
201 int sdQueryTerminal( void )
206 int sdTerminalFlush( void )
211 return fflush(PF_STDOUT);
215 void sdTerminalInit( void )
218 sConsoleHandle = GetStdHandle( STD_OUTPUT_HANDLE );
219 if( GetConsoleMode( sConsoleHandle, &mode ) )
221 /*printf("GetConsoleMode() mode is 0x%08X\n", mode );*/
222 sIsConsoleValid = TRUE;
226 /*printf("GetConsoleMode() failed\n", mode );*/
227 sIsConsoleValid = FALSE;
231 void sdTerminalTerm( void )