relicense to 0BSD
[pforth] / csrc / win32_console / pf_io_win32_console.c
index a081812..d8e5389 100644 (file)
-/* $Id$ */\r
-/***************************************************************\r
-** I/O subsystem for PForth for WIN32 systems.\r
-**\r
-** Use Windows Console so we can add the ANSI console commands needed to support HISTORY\r
-**\r
-** Author: Phil Burk\r
-** Copyright 1994 3DO, Phil Burk, Larry Polansky, David Rosenboom\r
-**\r
-** The pForth software code is dedicated to the public domain,\r
-** and any third party may reproduce, distribute and modify\r
-** the pForth software code or any derivative works thereof\r
-** without any compensation or license.  The pForth software\r
-** code is provided on an "as is" basis without any warranty\r
-** of any kind, including, without limitation, the implied\r
-** warranties of merchantability and fitness for a particular\r
-** purpose and their equivalents under the laws of any jurisdiction.\r
-**\r
-***************************************************************/\r
-\r
-#include "../pf_all.h"\r
-\r
-#if defined(WIN32) || defined(__NT__)\r
-\r
-#include <windows.h>\r
-\r
-#define ASCII_ESCAPE  (0x1B)\r
-\r
-static HANDLE sConsoleHandle = INVALID_HANDLE_VALUE;\r
-static int sIsConsoleValid = FALSE;\r
-\r
-typedef enum ConsoleState_e\r
-{\r
-       SDCONSOLE_STATE_IDLE = 0,\r
-       SDCONSOLE_STATE_GOT_ESCAPE,\r
-       SDCONSOLE_STATE_GOT_BRACKET\r
-\r
-} ConsoleState;\r
-\r
-static int sConsoleState = SDCONSOLE_STATE_IDLE;\r
-static int sParam1 = 0;\r
-static CONSOLE_SCREEN_BUFFER_INFO sScreenInfo;\r
-\r
-/******************************************************************/\r
-static void sdConsoleEmit( char c )\r
-{\r
-  /* Write a WCHAR in case we have compiled with Unicode support.\r
-   * Otherwise we will see '?' printed.*/\r
-       WCHAR  wc = (WCHAR) c;\r
-       DWORD count;\r
-       if( sIsConsoleValid )\r
-       {\r
-               WriteConsoleW(sConsoleHandle, &wc, 1, &count, NULL );\r
-       }\r
-       else\r
-       {\r
-          /* This will get called if we are redirecting to a file.*/\r
-               WriteFile(sConsoleHandle, &c, 1, &count, NULL );\r
-       }\r
-}\r
-\r
-/******************************************************************/\r
-static void sdClearScreen( void )\r
-{\r
-       if( GetConsoleScreenBufferInfo( sConsoleHandle, &sScreenInfo ) )\r
-       {\r
-               COORD XY;\r
-               int numNeeded;\r
-               DWORD count;\r
-               XY.X = 0;\r
-               XY.Y = sScreenInfo.srWindow.Top;\r
-               numNeeded = sScreenInfo.dwSize.X * (sScreenInfo.srWindow.Bottom - sScreenInfo.srWindow.Top + 1);\r
-               FillConsoleOutputCharacter(\r
-                       sConsoleHandle, ' ', numNeeded, XY, &count );\r
-               SetConsoleCursorPosition( sConsoleHandle, XY );\r
-       }\r
-}\r
-\r
-/******************************************************************/\r
-static void sdEraseEOL( void )\r
-{\r
-       if( GetConsoleScreenBufferInfo( sConsoleHandle, &sScreenInfo ) )\r
-       {\r
-               COORD savedXY;\r
-               int numNeeded;\r
-               DWORD count;\r
-               savedXY.X = sScreenInfo.dwCursorPosition.X;\r
-               savedXY.Y = sScreenInfo.dwCursorPosition.Y;\r
-               numNeeded = sScreenInfo.dwSize.X - savedXY.X;\r
-               FillConsoleOutputCharacter(\r
-                       sConsoleHandle, ' ', numNeeded, savedXY, &count );\r
-       }\r
-}\r
-\r
-/******************************************************************/\r
-static void sdCursorBack( int dx )\r
-{\r
-       if( GetConsoleScreenBufferInfo( sConsoleHandle, &sScreenInfo ) )\r
-       {\r
-               COORD XY;\r
-               XY.X = sScreenInfo.dwCursorPosition.X;\r
-               XY.Y = sScreenInfo.dwCursorPosition.Y;\r
-               XY.X -= dx;\r
-               if( XY.X < 0 ) XY.X = 0;\r
-               SetConsoleCursorPosition( sConsoleHandle, XY );\r
-       }\r
-}\r
-/******************************************************************/\r
-static void sdCursorForward( int dx )\r
-{\r
-       if( GetConsoleScreenBufferInfo( sConsoleHandle, &sScreenInfo ) )\r
-       {\r
-               COORD XY;\r
-               int width = sScreenInfo.dwSize.X;\r
-               XY.X = sScreenInfo.dwCursorPosition.X;\r
-               XY.Y = sScreenInfo.dwCursorPosition.Y;\r
-               XY.X += dx;\r
-               if( XY.X > width ) XY.X = width;\r
-               SetConsoleCursorPosition( sConsoleHandle, XY );\r
-       }\r
-}\r
-\r
-/******************************************************************/\r
-/* Use console mode I/O so that KEY and ?TERMINAL will work.\r
- * Parse ANSI escape sequences and call the appropriate cursor\r
- * control functions.\r
- */\r
-int  sdTerminalOut( char c )\r
-{\r
-       switch( sConsoleState )\r
-       {\r
-       case SDCONSOLE_STATE_IDLE:\r
-               switch( c )\r
-               {\r
-               case ASCII_ESCAPE:\r
-                       sConsoleState = SDCONSOLE_STATE_GOT_ESCAPE;\r
-                       break;\r
-               default:\r
-                       sdConsoleEmit( c );\r
-               }\r
-               break;\r
-\r
-       case SDCONSOLE_STATE_GOT_ESCAPE:\r
-               switch( c )\r
-               {\r
-               case '[':\r
-                       sConsoleState = SDCONSOLE_STATE_GOT_BRACKET;\r
-                       sParam1 = 0;\r
-                       break;\r
-               default:\r
-                       sConsoleState = SDCONSOLE_STATE_IDLE;\r
-                       sdConsoleEmit( c );\r
-               }\r
-               break;\r
-\r
-       case SDCONSOLE_STATE_GOT_BRACKET:\r
-               if( (c >= '0') && (c <= '9') )\r
-               {\r
-                       sParam1 = (sParam1 * 10) + (c - '0');\r
-               }\r
-               else\r
-               {\r
-                       sConsoleState = SDCONSOLE_STATE_IDLE;\r
-                       if( c == 'K')\r
-                       {\r
-                               sdEraseEOL();\r
-                       }\r
-                       else if( c == 'D' )\r
-                       {\r
-                               sdCursorBack( sParam1 );\r
-                       }\r
-                       else if( c == 'C' )\r
-                       {\r
-                               sdCursorForward( sParam1 );\r
-                       }\r
-                       else if( (c == 'J') && (sParam1 == 2) )\r
-                       {\r
-                               sdClearScreen();\r
-                       }\r
-               }\r
-               break;\r
-       }\r
-       return 0;\r
-}\r
-\r
-/* Needed cuz _getch() does not echo. */\r
-int  sdTerminalEcho( char c )\r
-{\r
-       sdConsoleEmit((char)(c));\r
-       return 0;\r
-}\r
-\r
-int  sdTerminalIn( void )\r
-{\r
-       return _getch();\r
-}\r
-\r
-int  sdQueryTerminal( void )\r
-{\r
-       return _kbhit();\r
-}\r
-\r
-int  sdTerminalFlush( void )\r
-{\r
-#ifdef PF_NO_FILEIO\r
-       return -1;\r
-#else\r
-       return fflush(PF_STDOUT);\r
-#endif\r
-}\r
-\r
-void sdTerminalInit( void )\r
-{\r
-       DWORD mode = 0;\r
-       sConsoleHandle = GetStdHandle( STD_OUTPUT_HANDLE );\r
-       if( GetConsoleMode( sConsoleHandle, &mode ) )\r
-       {\r
-          /*printf("GetConsoleMode() mode is 0x%08X\n", mode );*/\r
-               sIsConsoleValid = TRUE;\r
-       }\r
-       else\r
-       {\r
-          /*printf("GetConsoleMode() failed\n", mode );*/\r
-               sIsConsoleValid = FALSE;\r
-       }\r
-}\r
-\r
-void sdTerminalTerm( void )\r
-{\r
-}\r
-#endif\r
+/* $Id$ */
+/***************************************************************
+** I/O subsystem for PForth for WIN32 systems.
+**
+** Use Windows Console so we can add the ANSI console commands needed to support HISTORY
+**
+** Author: Phil Burk
+** Copyright 1994 3DO, Phil Burk, Larry Polansky, David Rosenboom
+**
+** Permission to use, copy, modify, and/or distribute this
+** software for any purpose with or without fee is hereby granted.
+**
+** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+** THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
+** CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+** FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+** CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+** OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+**
+***************************************************************/
+
+#include "../pf_all.h"
+
+#if defined(WIN32) || defined(__NT__)
+
+#include <windows.h>
+
+#define ASCII_ESCAPE  (0x1B)
+
+static HANDLE sConsoleHandle = INVALID_HANDLE_VALUE;
+static int sIsConsoleValid = FALSE;
+
+typedef enum ConsoleState_e
+{
+    SDCONSOLE_STATE_IDLE = 0,
+    SDCONSOLE_STATE_GOT_ESCAPE,
+    SDCONSOLE_STATE_GOT_BRACKET
+
+} ConsoleState;
+
+static int sConsoleState = SDCONSOLE_STATE_IDLE;
+static int sParam1 = 0;
+static CONSOLE_SCREEN_BUFFER_INFO sScreenInfo;
+
+/******************************************************************/
+static void sdConsoleEmit( char c )
+{
+  /* Write a WCHAR in case we have compiled with Unicode support.
+   * Otherwise we will see '?' printed.*/
+    WCHAR  wc = (WCHAR) c;
+    DWORD count;
+    if( sIsConsoleValid )
+    {
+        WriteConsoleW(sConsoleHandle, &wc, 1, &count, NULL );
+    }
+    else
+    {
+          /* This will get called if we are redirecting to a file.*/
+        WriteFile(sConsoleHandle, &c, 1, &count, NULL );
+    }
+}
+
+/******************************************************************/
+static void sdClearScreen( void )
+{
+    if( GetConsoleScreenBufferInfo( sConsoleHandle, &sScreenInfo ) )
+    {
+        COORD XY;
+        int numNeeded;
+        DWORD count;
+        XY.X = 0;
+        XY.Y = sScreenInfo.srWindow.Top;
+        numNeeded = sScreenInfo.dwSize.X * (sScreenInfo.srWindow.Bottom - sScreenInfo.srWindow.Top + 1);
+        FillConsoleOutputCharacter(
+            sConsoleHandle, ' ', numNeeded, XY, &count );
+        SetConsoleCursorPosition( sConsoleHandle, XY );
+    }
+}
+
+/******************************************************************/
+static void sdEraseEOL( void )
+{
+    if( GetConsoleScreenBufferInfo( sConsoleHandle, &sScreenInfo ) )
+    {
+        COORD savedXY;
+        int numNeeded;
+        DWORD count;
+        savedXY.X = sScreenInfo.dwCursorPosition.X;
+        savedXY.Y = sScreenInfo.dwCursorPosition.Y;
+        numNeeded = sScreenInfo.dwSize.X - savedXY.X;
+        FillConsoleOutputCharacter(
+            sConsoleHandle, ' ', numNeeded, savedXY, &count );
+    }
+}
+
+/******************************************************************/
+static void sdCursorBack( int dx )
+{
+    if( GetConsoleScreenBufferInfo( sConsoleHandle, &sScreenInfo ) )
+    {
+        COORD XY;
+        XY.X = sScreenInfo.dwCursorPosition.X;
+        XY.Y = sScreenInfo.dwCursorPosition.Y;
+        XY.X -= dx;
+        if( XY.X < 0 ) XY.X = 0;
+        SetConsoleCursorPosition( sConsoleHandle, XY );
+    }
+}
+/******************************************************************/
+static void sdCursorForward( int dx )
+{
+    if( GetConsoleScreenBufferInfo( sConsoleHandle, &sScreenInfo ) )
+    {
+        COORD XY;
+        int width = sScreenInfo.dwSize.X;
+        XY.X = sScreenInfo.dwCursorPosition.X;
+        XY.Y = sScreenInfo.dwCursorPosition.Y;
+        XY.X += dx;
+        if( XY.X > width ) XY.X = width;
+        SetConsoleCursorPosition( sConsoleHandle, XY );
+    }
+}
+
+/******************************************************************/
+/* Use console mode I/O so that KEY and ?TERMINAL will work.
+ * Parse ANSI escape sequences and call the appropriate cursor
+ * control functions.
+ */
+int  sdTerminalOut( char c )
+{
+    switch( sConsoleState )
+    {
+    case SDCONSOLE_STATE_IDLE:
+        switch( c )
+        {
+        case ASCII_ESCAPE:
+            sConsoleState = SDCONSOLE_STATE_GOT_ESCAPE;
+            break;
+        default:
+            sdConsoleEmit( c );
+        }
+        break;
+
+    case SDCONSOLE_STATE_GOT_ESCAPE:
+        switch( c )
+        {
+        case '[':
+            sConsoleState = SDCONSOLE_STATE_GOT_BRACKET;
+            sParam1 = 0;
+            break;
+        default:
+            sConsoleState = SDCONSOLE_STATE_IDLE;
+            sdConsoleEmit( c );
+        }
+        break;
+
+    case SDCONSOLE_STATE_GOT_BRACKET:
+        if( (c >= '0') && (c <= '9') )
+        {
+            sParam1 = (sParam1 * 10) + (c - '0');
+        }
+        else
+        {
+            sConsoleState = SDCONSOLE_STATE_IDLE;
+            if( c == 'K')
+            {
+                sdEraseEOL();
+            }
+            else if( c == 'D' )
+            {
+                sdCursorBack( sParam1 );
+            }
+            else if( c == 'C' )
+            {
+                sdCursorForward( sParam1 );
+            }
+            else if( (c == 'J') && (sParam1 == 2) )
+            {
+                sdClearScreen();
+            }
+        }
+        break;
+    }
+    return 0;
+}
+
+/* Needed cuz _getch() does not echo. */
+int  sdTerminalEcho( char c )
+{
+    sdConsoleEmit((char)(c));
+    return 0;
+}
+
+int  sdTerminalIn( void )
+{
+    return _getch();
+}
+
+int  sdQueryTerminal( void )
+{
+    return _kbhit();
+}
+
+int  sdTerminalFlush( void )
+{
+#ifdef PF_NO_FILEIO
+    return -1;
+#else
+    return fflush(PF_STDOUT);
+#endif
+}
+
+void sdTerminalInit( void )
+{
+    DWORD mode = 0;
+    sConsoleHandle = GetStdHandle( STD_OUTPUT_HANDLE );
+    if( GetConsoleMode( sConsoleHandle, &mode ) )
+    {
+          /*printf("GetConsoleMode() mode is 0x%08X\n", mode );*/
+        sIsConsoleValid = TRUE;
+    }
+    else
+    {
+          /*printf("GetConsoleMode() failed\n", mode );*/
+        sIsConsoleValid = FALSE;
+    }
+}
+
+void sdTerminalTerm( void )
+{
+}
+#endif