+++ /dev/null
-///////////////////////////////////////////////////////////////////////////////
-//Telnet Win32 : an ANSI telnet client.
-//Copyright (C) 1998-2000 Paul Brannan
-//Copyright (C) 1998 I.Ioannou
-//Copyright (C) 1997 Brad Johnson
-//
-//This program is free software; you can redistribute it and/or
-//modify it under the terms of the GNU General Public License
-//as published by the Free Software Foundation; either version 2
-//of the License, or (at your option) any later version.
-//
-//This program is distributed in the hope that it will be useful,
-//but WITHOUT ANY WARRANTY; without even the implied warranty of
-//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-//GNU General Public License for more details.
-//
-//You should have received a copy of the GNU General Public License
-//along with this program; if not, write to the Free Software
-//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-//
-//I.Ioannou
-//roryt@hol.gr
-//
-///////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// Module: ansiprsr.cpp
-//
-// Contents: ANSI parser base class
-//
-// Product: telnet
-//
-// Revisions: August 30, 1998 Paul Brannan <pbranna@clemson.edu>
-// July 29, 1998 pbranna@clemson.edu
-// June 15, 1998 pbranna@clemson.edu
-// May 19, 1998 pbranna@clemson.edu
-// 24 Dec, 1997 Andrey.V.Smilianets
-// 05. Sep.1997 roryt@hol.gr (I.Ioannou)
-// 11.May.1997 roryt@hol.gr (I.Ioannou)
-// 6.April.1997 roryt@hol.gr (I.Ioannou)
-// 5.April.1997 jbj@nounname.com
-// 30.M\84rz.1997 Titus_Boxberg@public.uni-hamburg.de
-// 14.Sept.1996 jbj@nounname.com
-// Version 2.0
-//
-// 13.Jul.1995 igor.milavec@uni-lj.si
-// Original code
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#include "precomp.h"
-
-const int ANSIColors[] = {BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE};
-
-// The constructor now takes different arguments and initializes different
-// variables (Paul Brannan 6/15/98)
-TANSIParser::TANSIParser(TConsole &RefConsole, KeyTranslator &RefKeyTrans,
- TScroller &RefScroller, TNetwork &RefNetwork,
- TCharmap &RefCharmap):
-TParser(RefConsole, RefKeyTrans, RefScroller, RefNetwork, RefCharmap) {
- Init();
- iSavedAttributes = (unsigned char) 7;
- // must also check to make sure the string is non-NULL
- // (Paul Brannan 5/8/98)
- if ((ini.get_dumpfile() != NULL) && (*ini.get_dumpfile() != '\0')){
- dumpfile = fopen(ini.get_dumpfile(), "wb");
- }else {
- dumpfile = NULL;
- }
- InPrintMode = 0;
- printfile = NULL;
-
- fast_write = ini.get_fast_write(); // Paul Brannan 6/28/98
- Scroller.init(&StripBuffer);
-}
-
-TANSIParser::~TANSIParser(){
- if (dumpfile) fclose (dumpfile);
- // Added I.Ioannou 06 April, 1997
- if (printfile != NULL) fclose (printfile);
-}
-
-// Created Init() function to initialize the parser but not clear the screen
-// (Paul Brannan 9/23/98)
-void TANSIParser::Init() {
- // Paul Brannan 6/25/98
- map_G0 = 'B'; map_G1 = 'B';
- Charmap.setmap(map_G0);
- current_map = 'B';
-
- ignore_margins = 0;
- vt52_mode = 0;
- print_ctrl = 0;
- newline_mode = false;
-
- KeyTrans.clear_ext_mode();
-
- iSavedCurY = 0; // Reset Variables
- iSavedCurX = 0;
- inGraphMode = 0;
- Console.SetScroll(-1, -1);
- Console.Normal(); // Reset Attributes
-
- // Set tabs stops
- resetTabStops();
-}
-
-void TANSIParser::ResetTerminal() {
- Init();
- Console.ClearScreen(); // Clear Screen
- Console.SetRawCursorPosition(0,0); // Home Cursor
-}
-void TANSIParser::SaveCurY(int iY){
- iSavedCurY=iY;
-}
-
-void TANSIParser::SaveCurX(int iX){
- iSavedCurX=iX;
-}
-
-void TANSIParser::resetTabStops() {
- for(int j = 0; j < MAX_TAB_POSITIONS; j++) {
- tab_stops[j] = 8 + j - (j%8);
- }
-}
-
-void TANSIParser::ConSetAttribute(unsigned char TextAttrib){
- // Paul Brannan 5/8/98
- // Made this go a little bit faster by changing from switch{} to an array
- // for the colors
- if(TextAttrib >= 30) {
- if(TextAttrib <= 37) {
- Console.SetForeground(ANSIColors[TextAttrib-30]);
- return;
- } else if((TextAttrib >= 40) && (TextAttrib <= 47)) {
- Console.SetBackground(ANSIColors[TextAttrib-40]);
- return;
- }
- }
-
- switch (TextAttrib){
- // Text Attributes
- case 0: Console.Normal(); break; // Normal video
- case 1: Console.HighVideo(); break; // High video
- case 2: Console.LowVideo(); break; // Low video
- case 4: Console.UnderlineOn(); break; // Underline on (I.Ioannou)
- case 5: Console.BlinkOn(); break; // Blink video
- // Corrected by I.Ioannou 11 May, 1997
- case 7: Console.ReverseOn(); break; // Reverse video
- case 8: break; // hidden
- // All from 10 thru 27 are hacked from linux kernel
- // I.Ioannou 06 April, 1997
- case 10:
- // I.Ioannou 04 Sep 1997 turn on/off high bit
- inGraphMode = 0;
- print_ctrl = 0;
- Charmap.setmap(current_map ? map_G1:map_G0); // Paul Brannan 6/25/98
- break; // ANSI X3.64-1979 (SCO-ish?)
- // Select primary font,
- // don't display control chars
- // if defined, don't set
- // bit 8 on output (normal)
- case 11:
- inGraphMode = 0;
- print_ctrl = 1;
- Charmap.setmap(0); // Paul Brannan 6/25/98
- break; // ANSI X3.64-1979 (SCO-ish?)
- // Select first alternate font,
- // let chars < 32 be displayed
- // as ROM chars
- case 12:
- inGraphMode = 1;
- print_ctrl = 1;
- Charmap.setmap(0); // Paul Brannan 6/25/98
- break; // ANSI X3.64-1979 (SCO-ish?)
- // Select second alternate font,
- // toggle high bit before
- // displaying as ROM char.
-
- case 21: // not really Low video
- case 22: Console.LowVideo(); break; // but this works good also
- case 24: Console.UnderlineOff(); break; // Underline off
- case 25: Console.BlinkOff(); break; // blink off
- // Corrected by I.Ioannou 11 May, 1997
- case 27: Console.ReverseOff(); break; //Reverse video off
-
- // Mutt needs this (Paul Brannan, Peter Jordan 12/31/98)
- // This is from the Linux kernel source
- case 38: /* ANSI X3.64-1979 (SCO-ish?)
- * Enables underscore, white foreground
- * with white underscore (Linux - use
- * default foreground).
- */
- Console.UnderlineOn();
- Console.SetForeground(ini.get_normal_fg());
- break;
- case 39: /* ANSI X3.64-1979 (SCO-ish?)
- * Disable underline option.
- * Reset colour to default? It did this
- * before...
- */
- Console.UnderlineOff();
- Console.SetForeground(ini.get_normal_fg());
- break;
- case 49:
- Console.SetBackground(ini.get_normal_bg());
- break;
-
- }
-}
-
-void TANSIParser::ConSetCursorPos(int x, int y) {
- if(ignore_margins)
- Console.SetRawCursorPosition(x, y);
- else
- Console.SetCursorPosition(x, y);
-}
-
-const char* TANSIParser::GetTerminalID()
-{
- return "\033[?1;2c";
-}
-
-// All of the Telnet protocol stuff has been moved to TTelHndl.cpp
-// This is more consistent with what OO should be
-// (Paul Brannan 6/15/98)
-
-#ifdef __BORLANDC__
-// argsused doesn't work on MSVC++
-#pragma argsused
-#endif
-
-// Use this for the VT100 flags (Paul Brannan 12/2/98)
-#define FLAG_DOLLAR 0x0001
-#define FLAG_QMARK 0x0002
-#define FLAG_GREATER 0x0004
-#define FLAG_LESS 0x0008
-#define FLAG_EXCLAM 0x0010
-#define FLAG_AMPERSAND 0x0020
-#define FLAG_SLASH 0x0040
-#define FLAG_EQUAL 0x0080
-#define FLAG_QUOTE 0x0100
-#define FLAG_OTHER 0x8000
-
-char* TANSIParser::ParseEscapeANSI(char* pszBuffer, char* pszBufferEnd)
-{
-
- // The buffer contains something like <ESC>[pA
- // where p is an optional decimal number specifying the count by which the
- // appropriate action should take place.
- // The pointer pszBuffer points us to the p, <ESC> and [ are
- // already 'consumed'
-
- // TITUS: Simplification of the code: Assume default count of 1 in case
- // there are no parameters.
- char tmpc;
- const int nParam = 10; // Maximum number of parameters
- int iParam[nParam] = {1, 0, 0, 0, 0}; // Assume 1 Parameter, Default 1
- int iCurrentParam = 0;
- DWORD flag = 0;
- int missing_param = 0;
-
- // Get parameters from escape sequence.
- while ((tmpc = *pszBuffer) <= '?') {
-
- if(tmpc < '0' || tmpc > '9') {
- // Check for parameter delimiter.
- if(tmpc == ';') {
- // This is a hack (Paul Brannan 6/27/98)
- if(*(pszBuffer - 1) == '[') missing_param = iCurrentParam+1;
- pszBuffer++;
- continue;
- }
-
- // It is legal to have control characters inside ANSI sequences
- // (Paul Brannan 6/26/98)
- if(tmpc < ' ') {
- Console.WriteCtrlChar(tmpc);
- pszBuffer++;
- continue;
- }
-
- // A new way of handling flags (Paul Brannan 12/2/98)
- switch(tmpc) {
- case '$': flag |= FLAG_DOLLAR; break;
- case '?': flag |= FLAG_QMARK; break;
- case '>': flag |= FLAG_GREATER; break;
- case '<': flag |= FLAG_LESS; break;
- case '!': flag |= FLAG_EXCLAM; break;
- case '&': flag |= FLAG_AMPERSAND; break;
- case '/': flag |= FLAG_SLASH; break;
- case '=': flag |= FLAG_EQUAL; break;
- case '\"': flag |= FLAG_QUOTE; break;
- default: flag |= FLAG_OTHER; break;
- }
-
- pszBuffer++;
- }
-
- // Got Numerical Parameter.
- iParam[iCurrentParam] = strtoul(pszBuffer, &pszBuffer, 10);
- if (iCurrentParam < nParam)
- iCurrentParam++;
- }
-
- //~~~ TITUS: Apparently the digit is optional (look at termcap or terminfo)
- // So: If there is no digit, assume a count of 1
-
- switch ((unsigned char)*pszBuffer++) {
- // Insert Character
- case '@':
- if(iParam[0] == 0) iParam[0] = 1; // Paul Brannan 9/1/98
- Console.InsertCharacter(iParam[0]); break;
- // Move cursor up.
- case 'A':
- if(iParam[0] == 0) iParam[0] = 1;
- Console.MoveCursorPosition(0, -iParam[0]); break;
- // Move cursor down.
- // Added by I.Ioannou 06 April, 1997
- case 'B':
- case 'e':
- if(iParam[0] == 0) iParam[0] = 1;
- Console.MoveCursorPosition(0, iParam[0]);
- break;
- // Move cursor right.
- // Added by I.Ioannou 06 April, 1997
- case 'C':
- case 'a':
- // Handle cursor size sequences (Jose Cesar Otero Rodriquez and
- // Paul Brannan, 3/27/1999)
- if(flag & FLAG_EQUAL) {
- switch(iParam[0]) {
- case 7: Console.SetCursorSize(50); break;
- case 11: Console.SetCursorSize(6); break;
- case 32: Console.SetCursorSize(0); break;
- default: Console.SetCursorSize(13);
- }
- } else {
- if(iParam[0] == 0) iParam[0] = 1;
- Console.MoveCursorPosition(iParam[0], 0);
- break;
- }
- // Move cursor left.
- case 'D':
- if(iParam[0] == 0) iParam[0] = 1;
- Console.MoveCursorPosition(-iParam[0], 0);
- break;
- // Move cursor to beginning of line, p lines down.
- // Added by I.Ioannou 06 April, 1997
- case 'E':
- Console.MoveCursorPosition(-Console.GetCursorX(), iParam[0]);
- break;
- // Moves active position to beginning of line, p lines up
- // Added by I.Ioannou 06 April, 1997
- // With '=' this changes the default fg color (Paul Brannan 6/27/98)
- case 'F':
- if(flag & FLAG_EQUAL)
- Console.setDefaultFg(iParam[0]);
- else
- Console.MoveCursorPosition(-Console.GetCursorX(), -iParam[0]);
- break;
- // Go to column p
- // Added by I.Ioannou 06 April, 1997
- // With '=' this changes the default bg color (Paul Brannan 6/27/98)
- case '`':
- case 'G': // 'G' is from Linux kernel sources
- if(flag & FLAG_EQUAL) {
- Console.setDefaultBg(iParam[0]);
- } else {
- if (iCurrentParam < 1) // Alter Default
- iParam[0] = 0;
- // this was backward, and we should subtract 1 from x
- // (Paul Brannan 5/27/98)
- ConSetCursorPos(iParam[0] - 1, Console.GetCursorY());
- }
- break;
- // Set cursor position.
- case 'f':
- case 'H':
- if (iCurrentParam < 2 || iParam[1] < 1)
- iParam[1] = 1;
- ConSetCursorPos(iParam[1] - 1, iParam[0] - 1);
- break;
- // Clear screen
- case 'J':
- if ( iCurrentParam < 1 ) iParam[0] = 0; // Alter Default
- switch (iParam[0]) {
- case 0: Console.ClearEOScreen(); break;
- case 1: Console.ClearBOScreen(); break;
- case 2:
- Console.ClearScreen();
- Console.SetRawCursorPosition(0, 0);
- break;
- }
- break;
- // Clear line
- case 'K':
- if (iCurrentParam < 1) // Alter Default
- iParam[0] = 0;
- switch (iParam[0]) {
- case 0: Console.ClearEOLine(); break;
- case 1: Console.ClearBOLine(); break;
- case 2: Console.ClearLine(); break;
- }
- break;
- // Insert p new, blank lines.
- // Added by I.Ioannou 06 April, 1997
- case 'L':
- {
- // for (int i = 1; i <= iParam[0]; i++)
- // This should speed things up a bit (Paul Brannan 9/2/98)
- Console.ScrollDown(Console.GetRawCursorY(), -1, iParam[0]);
- break;
- }
- // Delete p lines.
- // Added by I.Ioannou 06 April, 1997
- case 'M':
- {
- for (int i = 1; i <= iParam[0]; i++)
- // This should speed things up a bit (Paul Brannan 9/2/98)
- Console.ScrollDown(Console.GetRawCursorY(), -1, -1);
- break;
- }
- // DELETE CHAR
- case 'P':
- Console.DeleteCharacter(iParam[0]);
- break;
- // Scrolls screen up (down? -- PB) p lines,
- // Added by I.Ioannou 06 April, 1997
- // ANSI X3.64-1979 references this but I didn't
- // found it in any telnet implementation
- // note 05 Oct 97 : but SCO terminfo uses them, so uncomment them !!
- case 'S':
- {
- //for (int i = 1; i <= iParam[0]; i++)
- // This should speed things up a bit (Paul Brannan 9/2/98)
- Console.ScrollDown(-1, -1, -iParam[0]);
- break;
- }
- // Scrolls screen up p lines,
- // Added by I.Ioannou 06 April, 1997
- // ANSI X3.64-1979 references this but I didn't
- // found it in any telnet implementation
- // note 05 Oct 97 : but SCO terminfo uses them, so uncomment them !!
- case 'T':
- {
- // for (int i = 1; i <= iParam[0]; i++)
- // This should speed things up a bit (Paul Brannan 9/2/98)
- Console.ScrollDown(-1, -1, iParam[0]);
- break;
- }
- // Erases p characters up to the end of line
- // Added by I.Ioannou 06 April, 1997
- case 'X':
- {
- int iKeepX = Console.GetRawCursorX();
- int iKeepY = Console.GetRawCursorY();
- if (iParam[0] > Console.GetWidth())
- iParam[0] = Console.GetWidth(); // up to the end of line
- for ( int i = 1; i <= iParam[0]; i++ )
- Console.WriteString(" ", 1);
- Console.SetRawCursorPosition(iKeepX , iKeepY);
- break;
- }
- // Go back p tab stops
- // Added by I.Ioannou 06 April, 1997
- // Implemented by Paul Brannan, 4/13/2000
- case 'Z':
- {
- int x = Console.GetCursorX();
- for(int j = 0; x > 0 && j < iParam[0]; j++)
- while(x > 0 && tab_stops[j] == tab_stops[x]) x--;
- Console.SetCursorPosition(x, Console.GetCursorY());
- }
- break;
- // Get Terminal ID
- case 'c':
- {
- const char* szTerminalId = GetTerminalID();
- Network.WriteString(szTerminalId, strlen(szTerminalId));
- break;
- }
- // TITUS++ 2. November 1998: Repeat Character.
- case 'b':
- // isprint may be causing problems (Paul Brannan 3/27/99)
- // if ( isprint(last_char) ) {
- char buf[150]; // at most 1 line (max 132 chars)
-
- if ( iParam[0] > 149 ) iParam[0] = 149;
- memset(buf, last_char, iParam[0]);
- buf[iParam[0]] = 0;
- if ( fast_write )
- Console.WriteStringFast(buf, iParam[0]);
- else
- Console.WriteString(buf, iParam[0]);
- // } /* IF */
- break;
- // Go to line p
- // Added by I.Ioannou 06 April, 1997
- case 'd':
- if (iCurrentParam < 1) // Alter Default
- iParam[0] = 0;
- // this was backward, and we should subtract 1 from y
- // (Paul Brannan 5/27/98)
- ConSetCursorPos(Console.GetCursorX(), iParam[0] - 1);
- break;
- // iBCS2 tab erase
- // Added by I.Ioannou 06 April, 1997
- case 'g':
- if (iCurrentParam < 1) // Alter Default
- iParam[0] = 0;
- switch (iParam[0]) {
- case 0:
- {
- // Clear the horizontal tab stop at the current active position
- for(int j = 0; j < MAX_TAB_POSITIONS; j++) {
- int x = Console.GetCursorX();
- if(tab_stops[j] == x) tab_stops[j] = tab_stops[x + 1];
- }
- }
- break;
- case 2:
- // I think this might be "set as default?"
- break;
- case 3:
- {
- // Clear all tab stops
- for(int j = 0; j < MAX_TAB_POSITIONS; j++)
- tab_stops[j] = -1;
- }
- break;
- }
- break;
- // Set extended mode
- case 'h':
- {
- for (int i = 0; i < iCurrentParam; i++) {
- // Changed to a switch statement (Paul Brannan 5/27/98)
- if(flag & FLAG_QMARK) {
- switch(iParam[i]) {
- case 1: // App cursor keys
- KeyTrans.set_ext_mode(APP_KEY);
- break;
- case 2: // VT102 mode
- vt52_mode = 0;
- KeyTrans.unset_ext_mode(APP2_KEY);
- break;
- case 3: // 132 columns
- if(ini.get_wide_enable()) {
- Console.SetWindowSize(132, -1);
- }
- break;
- case 4: // smooth scrolling
- break;
- case 5: // Light background
- Console.Lightbg();
- break;
- case 6: // Stay in margins
- ignore_margins = 0;
- break;
- case 7:
- Console.setLineWrap(true);
- break;
- case 8: // Auto-repeat keys
- break;
- case 18: // Send FF to printer
- break;
- case 19: // Entire screen legal for printer
- break;
- case 25: // Visible cursor
- break;
- case 66: // Application numeric keypad
- break;
- default:
-#ifdef DEBUG
- Console.Beep();
-#endif
- break;
- }
- } else {
- switch(iParam[i]) {
- case 2: // Lock keyboard
- break;
- case 3: // Act upon control codes (PB 12/5/98)
- print_ctrl = 0;
- break;
- case 4: // Set insert mode
- Console.InsertMode(1);
- break;
- case 12: // Local echo off
- break;
- case 20: // Newline sends cr/lf
- KeyTrans.set_ext_mode(APP4_KEY);
- newline_mode = true;
- break;
- default:
-#ifdef DEBUG
- Console.Beep();
-#endif
- break;
- }
- }
- }
- }
- break;
- // Print Screen
- case 'i':
- if (iCurrentParam < 1)
- iParam[0]=0;
- switch (iParam[0]){
- case 0: break; // Print Screen
- case 1: break; // Print Line
- // Added I.Ioannou 06 April, 1997
- case 4:
- // Stop Print Log
- InPrintMode = 0;
- if ( printfile != NULL )
- fclose(printfile);
- break;
- case 5:
- // Start Print Log
- printfile = fopen(ini.get_printer_name(), "ab");
- if (printfile != NULL) InPrintMode = 1;
- break;
- }
- break;
- // Unset extended mode
- case 'l':
- {
- for (int i = 0; i < iCurrentParam; i++) {
- // Changed to a switch statement (Paul Brannan 5/27/98)
- if(flag & FLAG_QMARK) {
- switch(iParam[i]) {
- case 1: // Numeric cursor keys
- KeyTrans.unset_ext_mode(APP_KEY);
- break;
- case 2: // VT52 mode
- vt52_mode = 1;
- KeyTrans.set_ext_mode(APP2_KEY);
- break;
- case 3: // 80 columns
- if(ini.get_wide_enable()) {
- Console.SetWindowSize(80, -1);
- }
- break;
- case 4: // jump scrolling
- break;
- case 5: // Dark background
- Console.Darkbg();
- break;
- case 6: // Ignore margins
- ignore_margins = 1;
- break;
- case 7:
- Console.setLineWrap(false);
- break;
- case 8: // Auto-repeat keys
- break;
- case 19: // Only send scrolling region to printer
- break;
- case 25: // Invisible cursor
- break;
- case 66: // Numeric keypad
- break;
- default:
-#ifdef DEBUG
- Console.Beep();
-#endif
- break;
- }
- } else {
- switch(iParam[i]) {
- case 2: // Unlock keyboard
- break;
- case 3: // Display control codes (PB 12/5/98)
- print_ctrl = 1;
- break;
- case 4: // Set overtype mode
- Console.InsertMode(0);
- break;
- case 12: // Local echo on
- break;
- case 20: // sends lf only
- KeyTrans.unset_ext_mode(APP4_KEY);
- newline_mode = false;
- break;
- default:
-#ifdef DEBUG
- Console.Beep();
-#endif
- break;
- }
- }
- }
- }
- break;
- // Set color
- case 'm':
- if(missing_param) Console.Normal();
- if(iCurrentParam == 0) {
- Console.Normal();
- } else {
- for(int i = 0; i < iCurrentParam; i++)
- ConSetAttribute(iParam[i]);
- }
- break;
- // report cursor position Row X Col
- case 'n':
- if (iCurrentParam == 1 && iParam[0]==5) {
- // report the cursor position
- Network.WriteString("\x1B[0n", 4);
- break;
- }
- if (iCurrentParam == 1 && iParam[0]==6){
- // report the cursor position
- // The cursor position needs to be sent as a single string
- // (Paul Brannan 6/27/98)
- char szCursorReport[40] = "\x1B[";
-
- itoa(Console.GetCursorY() + 1,
- &szCursorReport[strlen(szCursorReport)], 10);
- strcat(szCursorReport, ";");
- itoa(Console.GetCursorX() + 1,
- &szCursorReport[strlen(szCursorReport)], 10);
- strcat(szCursorReport, "R");
-
- Network.WriteString(szCursorReport, strlen(szCursorReport));
-
- }
- break;
- // Miscellaneous weird sequences (Paul Brannan 6/27/98)
- case 'p':
- // Set conformance level
- if(flag & FLAG_QUOTE) {
- break;
- }
- // Soft terminal reset
- if(flag & FLAG_EXCLAM) {
- break;
- }
- // Report mode settings
- if(flag & FLAG_DOLLAR) {
- break;
- }
- break;
- // Scroll Screen
- case 'r':
- if (iCurrentParam < 1) {
- // Enable scrolling for entire display
- Console.SetScroll(-1, -1);
- break;
- }
- if (iCurrentParam >1) {
- // Enable scrolling from row1 to row2
- Console.SetScroll(iParam[0] - 1, iParam[1] - 1);
- // If the cursor is outside the scrolling range, fix it
- // (Paul Brannan 6/26/98)
- // if(Console.GetRawCursorY() < iParam[0] - 1) {
- // Console.SetRawCursorPosition(Console.GetCursorX(),
- // iParam[0] - 1);
- // }
- // if(Console.GetRawCursorY() > iParam[1] - 1) {
- // Console.SetRawCursorPosition(Console.GetCursorX(),
- // iParam[1] - 1);
- // }
- }
- // Move the cursor to the home position (Paul Brannan 12/2/98)
- Console.SetCursorPosition(0, 0);
- break;
- // Save cursor position
- case 's':
- SaveCurY(Console.GetRawCursorY());
- SaveCurX(Console.GetRawCursorX());
- break;
- // Restore cursor position
- case 'u':
- Console.SetRawCursorPosition(iSavedCurX, iSavedCurY);
- break;
- // DEC terminal report (Paul Brannan 6/28/98)
- case 'x':
- if(iParam[0])
- Network.WriteString("\033[3;1;1;128;128;1;0x", 20);
- else
- Network.WriteString("\033[2;1;1;128;128;1;0x", 20);
- break;
- default:
-#ifdef DEBUG
- Console.Beep();
-#endif
- break;
- }
-
- return pszBuffer;
-}
-
-#ifdef MTE_SUPPORT
-// Added by Frediano Ziglio, 5/31/2000
-// MTE extension
-// initially copied from ParseEscapeANSI
-char* TANSIParser::ParseEscapeMTE(char* pszBuffer, char* pszBufferEnd)
-{
- // The buffer contains something like <ESC>~pA
- // where p is an optional decimal number specifying the count by which the
- // appropriate action should take place.
- // The pointer pszBuffer points us to the p, <ESC> and ~ are
- // already 'consumed'
- // TITUS: Simplification of the code: Assume default count of 1 in case
- // there are no parameters.
- char tmpc;
- const int nParam = 10; // Maximum number of parameters
- int iParam[nParam] = {1, 0, 0, 0, 0}; // Assume 1 parameter, Default 1
- int iCurrentParam = 0;
- char sRepeat[2];
-
- // Get parameters from escape sequence.
- while ((tmpc = *pszBuffer) <= '?') {
- if(tmpc < '0' || tmpc > '9') {
- // Check for parameter delimiter.
- if(tmpc == ';') {
- pszBuffer++;
- continue;
- }
- pszBuffer++;
- }
-
- // Got Numerical Parameter.
- iParam[iCurrentParam] = strtoul(pszBuffer, &pszBuffer, 10);
- if (iCurrentParam < nParam)
- iCurrentParam++;
- }
-
- //~~~ TITUS: Apparently the digit is optional (look at termcap or terminfo)
- // So: If there is no digit, assume a count of 1
-
- switch ((unsigned char)*pszBuffer++) {
- case 'A':
- // set colors
- if (iCurrentParam < 2 )
- break;
- if (iParam[0] <= 15 && iParam[1] <= 15)
- Console.SetAttrib( (iParam[1] << 4) | iParam[0] );
- break;
-
- case 'R':
- // define region
- mteRegionXF = -1;
- if (iCurrentParam < 2 )
- break;
- mteRegionXF = iParam[1]-1;
- mteRegionYF = iParam[0]-1;
- break;
-
- case 'F':
- // fill with char
- {
- if (mteRegionXF == -1 || iCurrentParam < 1)
- break;
- sRepeat[0] = (char)iParam[0];
- sRepeat[1] = '\0';
- int xi = Console.GetCursorX(),yi = Console.GetCursorY();
- int xf = mteRegionXF;
- int yf = mteRegionYF;
- mteRegionXF = -1;
- for(int y=yi;y<=yf;++y)
- {
- Console.SetCursorPosition(xi,y);
- for(int x=xi;x<=xf;++x)
-
- Console.WriteStringFast(sRepeat,1);
- }
- }
- break;
-
- case 'S':
- // Scroll region
- {
- if (mteRegionXF == -1 || iCurrentParam < 2)
- break;
- int /*x = Console.GetCursorX(),*/y = Console.GetCursorY();
- // int xf = mteRegionXF;
- int yf = mteRegionYF;
- mteRegionXF = -1;
- // !!! don't use x during scroll
- int diff = (iParam[0]-1)-y;
- if (diff<0)
- Console.ScrollDown(y-1,yf,diff);
- else
- Console.ScrollDown(y,yf+1,diff);
- }
- break;
- // Meridian main version ??
- case 'x':
- // disable echo and line mode
- Network.set_local_echo(0);
- Network.set_line_mode(0);
- // Meridian Server handle cursor itself
- Console.SetCursorSize(0);
- break;
- // query ??
- case 'Q':
- if (iParam[0] == 1)
- Network.WriteString("\033vga.",5);
- break;
- default:
-#ifdef DEBUG
- Console.Beep();
-#endif
- break;
- }
-
- return pszBuffer;
- }
-#endif
-
-char* TANSIParser::ParseEscape(char* pszBuffer, char* pszBufferEnd) {
- char *pszChar;
-
- // Check if we have enough characters in buffer.
- if ((pszBufferEnd - pszBuffer) < 2)
- return pszBuffer;
-
- // I.Ioannou 04 Sep 1997
- // there is no need for pszBuffer++; after each command
-
- // Decode the command.
- pszBuffer++;
-
- switch (*pszBuffer++) {
- case 'A': // Cursor up
- Console.MoveCursorPosition(0, -1);
- break;
- // Cursor down
- case 'B':
- Console.MoveCursorPosition(0, 1);
- break;
- // Cursor right
- case 'C':
- Console.MoveCursorPosition(1, 0);
- break;
- // LF *or* cursor left (Paul Brannan 6/27/98)
- case 'D':
- if(vt52_mode)
- Console.MoveCursorPosition(-1, 0);
- else
- Console.index();
- break;
- // CR/LF (Paul Brannan 6/26/98)
- case 'E':
- Console.WriteCtrlString("\r\n", 2);
- break;
- // Special graphics char set (Paul Brannan 6/27/98)
- case 'F':
- Charmap.setmap('0');
- break;
- // ASCII char set (Paul Brannan 6/27/98)
- case 'G':
- Charmap.setmap('B');
- break;
- // Home cursor/tab set
- case 'H':
- if(ini.get_vt100_mode()) {
- int x = Console.GetCursorX();
- if(x != 0) {
- int t = tab_stops[x - 1];
- for(int j = x - 1; j >= 0 && tab_stops[j] == t; j--)
- tab_stops[j] = x;
- }
- } else {
- // I.Ioannou 04 Sep 1997 (0,0) not (1,1)
- ConSetCursorPos(0, 0);
- }
- break;
- // Reverse line feed (Paul Brannan 6/27/98)
- // FIX ME!!! reverse_index is wrong to be calling here
- // (Paul Brannan 12/2/98)
- case 'I':
- Console.reverse_index();
- break;
- // Erase end of screen
- case 'J':
- Console.ClearEOScreen();
- break;
- // Erase EOL
- case 'K':
- Console.ClearEOLine();
- break;
- // Scroll Up one line //Reverse index
- case 'M':
- Console.reverse_index();
- break;
- // Direct cursor addressing
- case 'Y':
- if ((pszBufferEnd - pszBuffer) >= 2){
- // if we subtract '\x1F', then we may end up with a negative
- // cursor position! (Paul Brannan 6/26/98)
- ConSetCursorPos(pszBuffer[1] - ' ', pszBuffer[0] - ' ');
- pszBuffer+=2;
- } else {
- pszBuffer--; // Paul Brannan 6/26/98
- }
- break;
- // Terminal ID Request
- case 'Z':
- {
- const char* szTerminalId = GetTerminalID();
- Network.WriteString(szTerminalId, strlen(szTerminalId));
- break;
- }
- // reset terminal to defaults
- case 'c':
- ResetTerminal();
- break;
- // Enter alternate keypad mode
- case '=':
- KeyTrans.set_ext_mode(APP3_KEY);
- break;
- // Exit alternate keypad mode
- case '>':
- KeyTrans.unset_ext_mode(APP3_KEY);
- break;
- // Enter ANSI mode
- case '<':
- KeyTrans.unset_ext_mode(APP2_KEY); // exit vt52 mode
- break;
- // Graphics processor on (See note 3)
- case '1':
- break;
- // Line size commands
- case '#': //Line size commands
- // (Paul Brannan 6/26/98)
- if(pszBuffer < pszBufferEnd) {
- switch(*pszBuffer++) {
- case '3': break; // top half of a double-height line
- case '4': break; // bottom half of a double-height line
- case '6': break; // current line becomes double-width
- case '8': Console.ClearScreen('E'); break;
- }
- } else {
- pszBuffer--;
- }
- break;
- // Graphics processor off (See note 3)
- case '2':
- break;
- // Save cursor and attribs
- case '7':
- SaveCurY(Console.GetRawCursorY());
- SaveCurX(Console.GetRawCursorX());
- iSavedAttributes = Console.GetAttrib();
- break;
- // Restore cursor position and attribs
- case '8':
- Console.SetRawCursorPosition(iSavedCurX, iSavedCurY);
- Console.SetAttrib(iSavedAttributes);
- break;
- // Set G0 map (Paul Brannan 6/25/98)
- case '(':
- if (pszBuffer < pszBufferEnd) {
- map_G0 = *pszBuffer;
- if(current_map == 0) Charmap.setmap(map_G0);
- pszBuffer++;
- } else {
- pszBuffer--;
- }
- break;
- // Set G1 map (Paul Brannan 6/25/98)
- case ')':
- if (pszBuffer < pszBufferEnd) {
- map_G1 = *pszBuffer;
- if(current_map == 1) Charmap.setmap(map_G1);
- pszBuffer++;
- } else {
- pszBuffer--;
- }
- break;
- // This doesn't do anything, as far as I can tell, but it does take
- // a parameter (Paul Brannan 6/27/98)
- case '%':
- if (pszBuffer < pszBufferEnd) {
- pszBuffer++;
- } else {
- pszBuffer--;
- }
- break;
- // ANSI escape sequence
- case '[':
- // Check if we have whole escape sequence in buffer.
- // This should not be isalpha anymore (Paul Brannan 9/1/98)
- pszChar = pszBuffer;
- while ((pszChar < pszBufferEnd) && (*pszChar <= '?'))
- pszChar++;
- if (pszChar == pszBufferEnd)
- pszBuffer -= 2;
- else
- pszBuffer = ParseEscapeANSI(pszBuffer, pszBufferEnd);
- break;
-#ifdef MTE_SUPPORT
- case '~':
- // Frediano Ziglio, 5/31/2000
- // Meridian Terminal Emulator extension
- // !!! same as ANSI
- // !!! should put in MTE procedure
- pszChar = pszBuffer;
- while ((pszChar < pszBufferEnd) && (*pszChar <= '?'))
- pszChar++;
- if (pszChar == pszBufferEnd)
- pszBuffer -= 2;
- else
- pszBuffer = ParseEscapeMTE(pszBuffer, pszBufferEnd);
- break;
-#endif
- default:
-#ifdef DEBUG
- Console.Beep();
-#endif
- break;
- }
-
- return pszBuffer;
-}
-
-// This function now only parses the ANSI buffer and does not do anything
-// with IAC sequences. That code has been moved to TTelHndl.cpp.
-// The scroller update routines have been moved to TScroll.cpp.
-// (Paul Brannan 6/15/98)
-char* TANSIParser::ParseBuffer(char* pszHead, char* pszTail){
- // copy into ANSI buffer
- char * pszResult;
-
- // Parse the buffer for ANSI or display
- while (pszHead < pszTail) {
- if(!ini.get_output_redir()) {
- pszResult = ParseANSIBuffer(pszHead, pszTail);
- } else {
- // Output is being redirected
- if(ini.get_strip_redir()) {
- // Skip the WriteFile() altogether and pass the buffer to a filter
- // Mark Miesfield 09/24/2000
- pszResult = PrintGoodChars(pszHead, pszTail);
- } else {
- DWORD Result;
- // Paul Brannan 7/29/98
- // Note that this has the unforunate effect of printing out
- // NULL (ascii 0) characters onto the screen
- if (!WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), pszHead,
- pszTail - pszHead, &Result, NULL)) pszResult = pszHead;
- pszResult = pszHead + Result;
- }
- }
- if (dumpfile)
- fwrite( pszHead, sizeof (char), pszResult-pszHead, dumpfile);
- if(ini.get_scroll_enable()) Scroller.update(pszHead, pszResult);
- if (pszResult == pszHead) break;
- pszHead = pszResult;
- }
- // return the new head to the buffer
- return pszHead;
-}
-
-// A simple routine to strip ANSI sequences
-// This isn't perfect, but it does an okay job (Paul Brannan 7/5/98)
-// Fixed a line counting bug (Paul Brannan 12/4/98)
-int TANSIParser::StripBuffer(char* pszHead, char* pszTail, int width) {
- int lines = 0, c = 0;
- char *pszBuf = pszHead;
-
- while(pszHead < pszTail) {
- if(iscntrl(*pszHead)) {
- switch(*(pszHead++)) {
- case 8:
- case 127:
- if(c>0) {
- if(!(c%width)) lines--;
- c--;
- pszBuf--;
- }
- break;
- case 10: lines++;
- case 13:
- *(pszBuf++) = *(pszHead - 1);
- c = 0;
- break;
- case 27:
- switch(*(pszHead++)) {
- case 'Y': pszHead += 2; break;
- case '#':
- case '(':
- case ')':
- case '%': pszHead++; break;
- case '[':
- while((pszHead < pszTail) && (*pszHead < '?'))
- pszHead++;
- pszHead++;
- break;
- }
- }
- } else {
- *(pszBuf++) = *(pszHead++);
- c++;
- }
- if(c != 0 && !(c%width))
- lines++;
- }
-
- // Fill in the end of the buffer with blanks
- while(pszBuf <= pszTail) *pszBuf++ = ' ';
-
- return lines;
-}
-
-char* TANSIParser::ParseANSIBuffer(char* pszBuffer, char* pszBufferEnd)
-{
- if(InPrintMode) {
- return PrintBuffer(pszBuffer, pszBufferEnd);
- }
-
- unsigned char tmpc = *(unsigned char *)pszBuffer;
-
- if(tmpc == 27) {
- return ParseEscape(pszBuffer, pszBufferEnd);
- }
-
-// if((fast_write && tmpc < 32) ||
-// !print_ctrl && (tmpc < 32 || (EightBit_Ansi &&
-// (tmpc > 128 && tmpc < 128 + ' ')))) {
-
- // We shouldn't print ctrl characters when fast write is enabled
- // and ctrl chars are disabled (Paul Brannan 9/1/98)
- if(tmpc < 32) {
- // From the Linux kernel (Paul Brannan 12/5/98):
- /* A bitmap for codes <32. A bit of 1 indicates that the code
- * corresponding to that bit number invokes some special action
- * (such as cursor movement) and should not be displayed as a
- * glyph unless the disp_ctrl mode is explicitly enabled.
- */
- const long CTRL_ACTION = 0x0d00ff81;
- const long CTRL_ALWAYS = 0x0800f501;
- if(!(((print_ctrl?CTRL_ALWAYS:CTRL_ACTION)>>tmpc)&1)) {
-
- Console.WriteString((char *)&tmpc, 1);
- pszBuffer++;
- return pszBuffer;
- }
-
- switch (tmpc) {
- case 0:
- pszBuffer++;
- break;
-
- // I.Ioannou 5/30/98
- case 7:
- Console.Beep();
- pszBuffer++;
- break;
-
- // destructive backspace
- case 8:
- // Added option for destructive backspace (Paul Brannan 5/13/98)
- // Changed to ConWriteCtrlString so that the cursor position can be
- // updated (Paul Brannan 5/25/98)
- if(ini.get_dstrbksp()) {
- Console.WriteCtrlChar('\b');
- Console.WriteString(" ", 1);
- Console.WriteCtrlChar('\b');
- }
- else Console.WriteCtrlChar('\b');
- pszBuffer++;
- break;
-
- // horizontal tab
- case 9:
- {
- pszBuffer++;
- int x = Console.GetCursorX();
- if(x != -1)
- Console.SetCursorPosition(tab_stops[x], Console.GetCursorY());
- }
- break;
-
- // Line Feed Char
- case 10:
- // Test for local echo (Paul Brannan 8/25/98)
- if(Network.get_local_echo() || newline_mode) // &&
- Console.WriteCtrlChar('\x0d');
- Console.WriteCtrlChar('\x0a');
- pszBuffer++;
- break;
-
- // form feed
- case 12:
- pszBuffer++;
- Console.ClearScreen();
- Console.SetRawCursorPosition(Console.GetCursorX(), 1); // changed fm 1
- break;
-
- case 13:
- Console.WriteCtrlChar('\x0d');
- pszBuffer++;
-
- break;
-
- case 14: // shift out of alternate chararcter set
- pszBuffer++;
- Charmap.setmap(map_G1); // Paul Brannan 6/25/98
- current_map = 1;
- break;
-
- case 15: // shift in
- pszBuffer++;
- Charmap.setmap(map_G0); // Paul Brannan 6/25/98
- current_map = 0;
- break;
-
- // Paul Brannan 9/1/98 - Is this okay?
- default:
- pszBuffer++;
- }
-
- return pszBuffer;
- }
-
- // added by I.Ioannou 06 April, 1997
- // In 8 bit systems the server may send 0x9b instead of ESC[
- // Well, this will produce troubles in Greek 737 Code page
- // which uses 0x9b as the small "delta" - and I thing that there
- // is another European country with the same problem.
- // If we have to stay 8-bit clean we may have to
- // give the ability of ROM characters (ESC[11m),
- // for striped 8'th bit (ESC[12m) as SCO does,
- // or a parameter at compile (or run ?) time.
- // We now check for a flag in the ini file (Paul Brannan 5/13/98)
- // We also handle any 8-bit ESC sequence (Paul Brannan 6/28/98)
- if(ini.get_eightbit_ansi() && (tmpc > 128 && tmpc < 128 + ' ')) {
- // There's a chance the sequence might not parse. If this happens
- // then pszBuffer will be one character too far back, since
- // ParseEscape is expecting two characters, not one.
- // In that case we must handle it.
- char *pszCurrent = pszBuffer;
- pszBuffer = ParseEscape(pszBuffer, pszBufferEnd);
- if(pszBuffer < pszCurrent) pszBuffer = pszCurrent;
- }
-
- char* pszCurrent = pszBuffer + 1;
- // I.Ioannou 04 Sep 1997 FIXME with ESC[11m must show chars < 32
- // Fixed (Paul Brannan 6/28/98)
- while ((pszCurrent < pszBufferEnd) && (!iscntrl(*pszCurrent))) {
- // I.Ioannou 04 Sep 1997 strip on high bit
- if ( (inGraphMode) && (*pszCurrent > (char)32) )
- *pszCurrent |= 0x80 ;
- pszCurrent++;
- }
-
- // Note that this may break dumpfiles slightly.
- // If 'B' is set to anything other than ASCII, this will cause problems
- // (Paul Brannan 6/28/98)
- if(current_map != 'B' && Charmap.enabled)
- Charmap.translate_buffer(pszBuffer, pszCurrent);
-
- last_char = *(pszCurrent-1); // TITUS++: Remember last char
-
- if(fast_write) {
- pszBuffer += Console.WriteStringFast(pszBuffer,
- pszCurrent - pszBuffer);
- } else {
- pszBuffer += Console.WriteString(pszBuffer,
- pszCurrent - pszBuffer);
- }
-
- return pszBuffer;
-}
-
-// Added by I.Ioannou 06 April, 1997
-// Print the buffer until you reach ESC[4i
-char* TANSIParser::PrintBuffer(char* pszBuffer, char* pszBufferEnd) {
- // Check if we have enough characters in buffer.
- if ((pszBufferEnd - pszBuffer) < 4)
- return pszBuffer;
- char *tmpChar;
-
- tmpChar = pszBuffer;
- if ( *tmpChar == 27 ) {
- tmpChar++;
- if ( *tmpChar == '[' ) {
- tmpChar++;
- if ( *tmpChar == '4' ) {
- tmpChar++;
- if ( *tmpChar == 'i' ) {
- InPrintMode = 0; // Stop Print Log
- if ( printfile != NULL )
- fclose(printfile);
- pszBuffer += 4;
- return pszBuffer;
- }
- }
- }
- }
-
- if (printfile != NULL) {
- fputc( *pszBuffer, printfile);
- pszBuffer++;
- } else
- InPrintMode = 0;
-
- return pszBuffer;
-}
-
-/* - PrintGoodChars( pszHead, pszTail ) - - - - - - - - - - - - - - - - - - -
--*
-
- Mark Miesfield 09/24/2000
-
- Prints the characters in a buffer, from the specified head to the specified
- tail, to standard out, skipping any control characters or ANSI escape
- sequences.
-
- Parameters on entry:
- pszHead -> Starting point in buffer.
-
- pszTail -> Ending point in buffer.
-
- Returns:
- Pointer to the first character in the buffer that was not output to
- standard out. (Since no error checking is done, this is in effect
- pszTail.)
-
- Side Effects:
- None.
-* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-*/
-char * TANSIParser::PrintGoodChars( char * pszHead, char * pszTail ) {
-
- while ( pszHead < pszTail ) {
- if ( iscntrl( *pszHead ) ) {
- switch ( *(pszHead++) ) {
- case 10 :
- putc( 10, stdout );
- break;
-
- case 13 :
- putc( 13, stdout );
- break;
-
- case 27:
- switch ( *(pszHead++) ) {
- case 'Y':
- pszHead += 2;
- break;
-
- case '#':
- case '(':
- case ')':
- case '%': pszHead++; break;
- case '[':
- while ( (pszHead < pszTail) && (*pszHead < '?') )
- pszHead++;
- pszHead++;
- break;
-
- default :
- break;
- }
- break;
-
- default :
- break;
- }
- }
- else
- putc( *(pszHead++), stdout );
- }
- return ( pszTail );
-}
-// End of function: PrintGoodChars( pszHead, pszTail )