ansiprsr.cpp
来自「一个类似windows」· C++ 代码 · 共 1,477 行 · 第 1/3 页
CPP
1,477 行
///////////////////////////////////////////////////////////////////////////////
//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剅z.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 <windows.h>
#include <string.h>
#include "ansiprsr.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]);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?