ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ansiprsr.cpp
Go to the documentation of this file.
00001 
00002 //Telnet Win32 : an ANSI telnet client.
00003 //Copyright (C) 1998-2000 Paul Brannan
00004 //Copyright (C) 1998 I.Ioannou
00005 //Copyright (C) 1997 Brad Johnson
00006 //
00007 //This program is free software; you can redistribute it and/or
00008 //modify it under the terms of the GNU General Public License
00009 //as published by the Free Software Foundation; either version 2
00010 //of the License, or (at your option) any later version.
00011 //
00012 //This program is distributed in the hope that it will be useful,
00013 //but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 //GNU General Public License for more details.
00016 //
00017 //You should have received a copy of the GNU General Public License
00018 //along with this program; if not, write to the Free Software
00019 //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00020 //
00021 //I.Ioannou
00022 //roryt@hol.gr
00023 //
00025 
00027 //
00028 // Module:      ansiprsr.cpp
00029 //
00030 // Contents:    ANSI parser base class
00031 //
00032 // Product:     telnet
00033 //
00034 // Revisions: August 30, 1998 Paul Brannan <pbranna@clemson.edu>
00035 //            July 29, 1998 pbranna@clemson.edu
00036 //            June 15, 1998 pbranna@clemson.edu
00037 //            May 19, 1998  pbranna@clemson.edu
00038 //            24 Dec, 1997  Andrey.V.Smilianets
00039 //            05. Sep.1997  roryt@hol.gr (I.Ioannou)
00040 //            11.May.1997   roryt@hol.gr (I.Ioannou)
00041 //            6.April.1997  roryt@hol.gr (I.Ioannou)
00042 //            5.April.1997  jbj@nounname.com
00043 //            30.M„rz.1997  Titus_Boxberg@public.uni-hamburg.de
00044 //            14.Sept.1996  jbj@nounname.com
00045 //            Version 2.0
00046 //
00047 //            13.Jul.1995   igor.milavec@uni-lj.si
00048 //                    Original code
00049 //
00051 
00052 //#include <windows.h>
00053 #include "precomp.h"
00054 
00055 const int ANSIColors[] = {BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE};
00056 
00057 // The constructor now takes different arguments and initializes different
00058 // variables (Paul Brannan 6/15/98)
00059 TANSIParser::TANSIParser(TConsole &RefConsole, KeyTranslator &RefKeyTrans,
00060                          TScroller &RefScroller, TNetwork &RefNetwork,
00061                          TCharmap &RefCharmap):
00062 TParser(RefConsole, RefKeyTrans, RefScroller, RefNetwork, RefCharmap) {
00063     Init();
00064     iSavedAttributes = (unsigned char) 7;
00065     // must also check to make sure the string is non-NULL
00066     // (Paul Brannan 5/8/98)
00067     if ((ini.get_dumpfile() != NULL) && (*ini.get_dumpfile() != '\0')){
00068         dumpfile = fopen(ini.get_dumpfile(), "wb");
00069     }else {
00070         dumpfile = NULL;
00071     }
00072     InPrintMode = 0;
00073     printfile = NULL;
00074 
00075     fast_write = ini.get_fast_write(); // Paul Brannan 6/28/98
00076     Scroller.init(&StripBuffer);
00077 }
00078 
00079 TANSIParser::~TANSIParser(){
00080     if (dumpfile) fclose (dumpfile);
00081     // Added I.Ioannou 06 April, 1997
00082     if (printfile != NULL) fclose (printfile);
00083 }
00084 
00085 // Created Init() function to initialize the parser but not clear the screen
00086 // (Paul Brannan 9/23/98)
00087 void TANSIParser::Init() {
00088     // Paul Brannan 6/25/98
00089     map_G0 = 'B'; map_G1 = 'B';
00090     Charmap.setmap(map_G0);
00091     current_map = 'B';
00092 
00093     ignore_margins = 0;
00094     vt52_mode = 0;
00095     print_ctrl = 0;
00096     newline_mode = false;
00097 
00098     KeyTrans.clear_ext_mode();
00099 
00100     iSavedCurY = 0;                         // Reset Variables
00101     iSavedCurX = 0;
00102     inGraphMode = 0;
00103     Console.SetScroll(-1, -1);
00104     Console.Normal();                       // Reset Attributes
00105 
00106     // Set tabs stops
00107     resetTabStops();
00108 }
00109 
00110 void TANSIParser::ResetTerminal() {
00111     Init();
00112     Console.ClearScreen();                  // Clear Screen
00113     Console.SetRawCursorPosition(0,0);      // Home Cursor
00114 }
00115 void TANSIParser::SaveCurY(int iY){
00116     iSavedCurY=iY;
00117 }
00118 
00119 void TANSIParser::SaveCurX(int iX){
00120     iSavedCurX=iX;
00121 }
00122 
00123 void TANSIParser::resetTabStops() {
00124     for(int j = 0; j < MAX_TAB_POSITIONS; j++) {
00125         tab_stops[j] = 8 + j - (j%8);
00126     }
00127 }
00128 
00129 void TANSIParser::ConSetAttribute(unsigned char TextAttrib){
00130     // Paul Brannan 5/8/98
00131     // Made this go a little bit faster by changing from switch{} to an array
00132     // for the colors
00133     if(TextAttrib >= 30) {
00134         if(TextAttrib <= 37) {
00135             Console.SetForeground(ANSIColors[TextAttrib-30]);
00136             return;
00137         } else if((TextAttrib >= 40) && (TextAttrib <= 47)) {
00138             Console.SetBackground(ANSIColors[TextAttrib-40]);
00139             return;
00140         }
00141     }
00142 
00143     switch (TextAttrib){
00144         // Text Attributes
00145     case 0: Console.Normal();           break;  // Normal video
00146     case 1: Console.HighVideo();        break;  // High video
00147     case 2: Console.LowVideo();         break;  // Low video
00148     case 4: Console.UnderlineOn();      break;  // Underline on (I.Ioannou)
00149     case 5: Console.BlinkOn();          break;  // Blink video
00150         // Corrected by I.Ioannou 11 May, 1997
00151     case 7: Console.ReverseOn();        break;  // Reverse video
00152     case 8:                             break;  // hidden
00153         // All from 10 thru 27 are hacked from linux kernel
00154         // I.Ioannou 06 April, 1997
00155     case 10:
00156         //  I.Ioannou 04 Sep 1997 turn on/off high bit
00157         inGraphMode = 0;
00158         print_ctrl = 0;
00159         Charmap.setmap(current_map ? map_G1:map_G0); // Paul Brannan 6/25/98
00160         break; // ANSI X3.64-1979 (SCO-ish?)
00161         // Select primary font,
00162         // don't display control chars
00163         // if defined, don't set
00164         // bit 8 on output (normal)
00165     case 11:
00166         inGraphMode = 0;
00167         print_ctrl = 1;
00168         Charmap.setmap(0); // Paul Brannan 6/25/98
00169         break; // ANSI X3.64-1979 (SCO-ish?)
00170         // Select first alternate font,
00171         // let chars < 32 be displayed
00172         // as ROM chars
00173     case 12:
00174         inGraphMode = 1;
00175         print_ctrl = 1;
00176         Charmap.setmap(0); // Paul Brannan 6/25/98
00177         break; // ANSI X3.64-1979 (SCO-ish?)
00178         // Select second alternate font,
00179         // toggle high bit before
00180         // displaying as ROM char.
00181 
00182     case 21:                                    // not really Low video
00183     case 22: Console.LowVideo();        break;  // but this works good also
00184     case 24: Console.UnderlineOff();    break;  // Underline off
00185     case 25: Console.BlinkOff();        break;  // blink off
00186         // Corrected by I.Ioannou 11 May, 1997
00187     case 27: Console.ReverseOff();      break;  //Reverse video off
00188 
00189     // Mutt needs this (Paul Brannan, Peter Jordan 12/31/98)
00190     // This is from the Linux kernel source
00191     case 38: /* ANSI X3.64-1979 (SCO-ish?)
00192               * Enables underscore, white foreground
00193               * with white underscore (Linux - use
00194               * default foreground).
00195               */
00196             Console.UnderlineOn();
00197             Console.SetForeground(ini.get_normal_fg());
00198             break;
00199     case 39: /* ANSI X3.64-1979 (SCO-ish?)
00200               * Disable underline option.
00201               * Reset colour to default? It did this
00202               * before...
00203               */
00204             Console.UnderlineOff();
00205             Console.SetForeground(ini.get_normal_fg());
00206             break;
00207     case 49:
00208             Console.SetBackground(ini.get_normal_bg());
00209             break;
00210 
00211     }
00212 }
00213 
00214 void TANSIParser::ConSetCursorPos(int x, int y) {
00215     if(ignore_margins)
00216         Console.SetRawCursorPosition(x, y);
00217     else
00218         Console.SetCursorPosition(x, y);
00219 }
00220 
00221 const char* TANSIParser::GetTerminalID()
00222 {
00223     return "\033[?1;2c";
00224 }
00225 
00226 // All of the Telnet protocol stuff has been moved to TTelHndl.cpp
00227 // This is more consistent with what OO should be
00228 // (Paul Brannan 6/15/98)
00229 
00230 #ifdef __BORLANDC__
00231 // argsused doesn't work on MSVC++
00232 #pragma argsused
00233 #endif
00234 
00235 // Use this for the VT100 flags (Paul Brannan 12/2/98)
00236 #define FLAG_DOLLAR     0x0001
00237 #define FLAG_QMARK      0x0002
00238 #define FLAG_GREATER    0x0004
00239 #define FLAG_LESS       0x0008
00240 #define FLAG_EXCLAM     0x0010
00241 #define FLAG_AMPERSAND  0x0020
00242 #define FLAG_SLASH      0x0040
00243 #define FLAG_EQUAL      0x0080
00244 #define FLAG_QUOTE      0x0100
00245 #define FLAG_OTHER      0x8000
00246 
00247 char* TANSIParser::ParseEscapeANSI(char* pszBuffer, char* pszBufferEnd)
00248 {
00249 
00250     //  The buffer contains something like <ESC>[pA
00251     //  where p is an optional decimal number specifying the count by which the
00252     //  appropriate action should take place.
00253     //  The pointer pszBuffer points us to the p, <ESC> and [ are
00254     //  already 'consumed'
00255 
00256     //  TITUS: Simplification of the code: Assume default count of 1 in case
00257     //  there are no parameters.
00258     char tmpc;
00259     const int nParam = 10;  // Maximum number of parameters
00260     int iParam[nParam] = {1, 0, 0, 0, 0};   // Assume 1 Parameter, Default 1
00261     int iCurrentParam = 0;
00262     DWORD flag = 0;
00263     int missing_param = 0;
00264 
00265     // Get parameters from escape sequence.
00266     while ((tmpc = *pszBuffer) <= '?') {
00267 
00268         if(tmpc < '0' || tmpc > '9') {
00269             // Check for parameter delimiter.
00270             if(tmpc == ';') {
00271                 // This is a hack (Paul Brannan 6/27/98)
00272                 if(*(pszBuffer - 1) == '[') missing_param = iCurrentParam+1;
00273                 pszBuffer++;
00274                 continue;
00275             }
00276 
00277             // It is legal to have control characters inside ANSI sequences
00278             // (Paul Brannan 6/26/98)
00279             if(tmpc < ' ') {
00280                 Console.WriteCtrlChar(tmpc);
00281                 pszBuffer++;
00282                 continue;
00283             }
00284 
00285             // A new way of handling flags (Paul Brannan 12/2/98)
00286             switch(tmpc) {
00287             case '$': flag |= FLAG_DOLLAR; break;
00288             case '?': flag |= FLAG_QMARK; break;
00289             case '>': flag |= FLAG_GREATER; break;
00290             case '<': flag |= FLAG_LESS; break;
00291             case '!': flag |= FLAG_EXCLAM; break;
00292             case '&': flag |= FLAG_AMPERSAND; break;
00293             case '/': flag |= FLAG_SLASH; break;
00294             case '=': flag |= FLAG_EQUAL; break;
00295             case '\"': flag |= FLAG_QUOTE; break;
00296             default: flag |= FLAG_OTHER; break;
00297             }
00298 
00299             pszBuffer++;
00300         }
00301 
00302         //  Got Numerical Parameter.
00303         iParam[iCurrentParam] = strtoul(pszBuffer, &pszBuffer, 10);
00304         if (iCurrentParam < nParam)
00305             iCurrentParam++;
00306     }
00307 
00308     //~~~ TITUS: Apparently the digit is optional (look at termcap or terminfo)
00309     // So: If there is no digit, assume a count of 1
00310 
00311     switch ((unsigned char)*pszBuffer++) {
00312         // Insert Character
00313         case '@':
00314             if(iParam[0] == 0) iParam[0] = 1; // Paul Brannan 9/1/98
00315             Console.InsertCharacter(iParam[0]); break;
00316         // Move cursor up.
00317         case 'A':
00318             if(iParam[0] == 0) iParam[0] = 1;
00319             Console.MoveCursorPosition(0, -iParam[0]); break;
00320         // Move cursor down.
00321         // Added by I.Ioannou 06 April, 1997
00322         case 'B':
00323         case 'e':
00324             if(iParam[0] == 0) iParam[0] = 1;
00325             Console.MoveCursorPosition(0, iParam[0]);
00326             break;
00327         // Move cursor right.
00328         // Added by I.Ioannou 06 April, 1997
00329         case 'C':
00330         case 'a':
00331             // Handle cursor size sequences (Jose Cesar Otero Rodriquez and
00332             // Paul Brannan, 3/27/1999)
00333             if(flag & FLAG_EQUAL) {
00334                 switch(iParam[0]) {
00335                 case 7: Console.SetCursorSize(50); break;
00336                 case 11: Console.SetCursorSize(6); break;
00337                 case 32: Console.SetCursorSize(0); break;
00338                 default: Console.SetCursorSize(13);
00339                 }
00340             } else {
00341                 if(iParam[0] == 0) iParam[0] = 1;
00342                 Console.MoveCursorPosition(iParam[0], 0);
00343                 break;
00344             }
00345         // Move cursor left.
00346         case 'D':
00347             if(iParam[0] == 0) iParam[0] = 1;
00348             Console.MoveCursorPosition(-iParam[0], 0);
00349             break;
00350         // Move cursor to beginning of line, p lines down.
00351         // Added by I.Ioannou 06 April, 1997
00352         case 'E':
00353             Console.MoveCursorPosition(-Console.GetCursorX(), iParam[0]);
00354             break;
00355         // Moves active position to beginning of line, p lines up
00356         // Added by I.Ioannou 06 April, 1997
00357         // With '=' this changes the default fg color (Paul Brannan 6/27/98)
00358         case 'F':
00359             if(flag & FLAG_EQUAL)
00360                 Console.setDefaultFg(iParam[0]);
00361             else
00362                 Console.MoveCursorPosition(-Console.GetCursorX(), -iParam[0]);
00363             break;
00364         // Go to column p
00365         // Added by I.Ioannou 06 April, 1997
00366         // With '=' this changes the default bg color (Paul Brannan 6/27/98)
00367         case '`':
00368         case 'G': // 'G' is from Linux kernel sources
00369             if(flag & FLAG_EQUAL) {
00370                 Console.setDefaultBg(iParam[0]);
00371             } else {
00372                 if (iCurrentParam < 1)          // Alter Default
00373                     iParam[0] = 0;
00374                 // this was backward, and we should subtract 1 from x
00375                 // (Paul Brannan 5/27/98)
00376                 ConSetCursorPos(iParam[0] - 1, Console.GetCursorY());
00377             }
00378             break;
00379         // Set cursor position.
00380         case 'f':
00381         case 'H':
00382             if (iCurrentParam < 2 || iParam[1] < 1)
00383                 iParam[1] = 1;
00384             ConSetCursorPos(iParam[1] - 1, iParam[0] - 1);
00385             break;
00386         // Clear screen
00387         case 'J':
00388             if ( iCurrentParam < 1 ) iParam[0] = 0; // Alter Default
00389             switch (iParam[0]) {
00390                 case 0: Console.ClearEOScreen(); break;
00391                 case 1: Console.ClearBOScreen(); break;
00392                 case 2:
00393                     Console.ClearScreen();
00394                     Console.SetRawCursorPosition(0, 0);
00395                     break;
00396             }
00397             break;
00398         // Clear line
00399         case 'K':
00400             if (iCurrentParam < 1)          // Alter Default
00401                 iParam[0] = 0;
00402             switch (iParam[0]) {
00403                 case 0: Console.ClearEOLine(); break;
00404                 case 1: Console.ClearBOLine(); break;
00405                 case 2: Console.ClearLine(); break;
00406             }
00407             break;
00408         //  Insert p new, blank lines.
00409         // Added by I.Ioannou 06 April, 1997
00410         case 'L':
00411             {
00412                 // for (int i = 1; i <= iParam[0]; i++)
00413                 // This should speed things up a bit (Paul Brannan 9/2/98)
00414                 Console.ScrollDown(Console.GetRawCursorY(), -1, iParam[0]);
00415                 break;
00416             }
00417         //  Delete p lines.
00418         // Added by I.Ioannou 06 April, 1997
00419         case 'M':
00420             {
00421                 for (int i = 1; i <= iParam[0]; i++)
00422                 // This should speed things up a bit (Paul Brannan 9/2/98)
00423                 Console.ScrollDown(Console.GetRawCursorY(), -1, -1);
00424                 break;
00425             }
00426         // DELETE CHAR
00427         case 'P':
00428             Console.DeleteCharacter(iParam[0]);
00429             break;
00430         // Scrolls screen up (down? -- PB) p lines,
00431         // Added by I.Ioannou 06 April, 1997
00432         // ANSI X3.64-1979 references this but I didn't
00433         // found it in any telnet implementation
00434         // note 05 Oct 97  : but SCO terminfo uses them, so uncomment them !!
00435         case 'S':
00436             {
00437                 //for (int i = 1; i <= iParam[0]; i++)
00438                 // This should speed things up a bit (Paul Brannan 9/2/98)
00439                 Console.ScrollDown(-1, -1, -iParam[0]);
00440                 break;
00441             }
00442         // Scrolls screen up p lines,
00443         // Added by I.Ioannou 06 April, 1997
00444         // ANSI X3.64-1979 references this but I didn't
00445         // found it in any telnet implementation
00446         // note 05 Oct 97  : but SCO terminfo uses them, so uncomment them !!
00447         case 'T':
00448             {
00449                 // for (int i = 1; i <= iParam[0]; i++)
00450                 // This should speed things up a bit (Paul Brannan 9/2/98)
00451                 Console.ScrollDown(-1, -1, iParam[0]);
00452                 break;
00453             }
00454         //  Erases p characters up to the end of line
00455         // Added by I.Ioannou 06 April, 1997
00456         case 'X':
00457             {
00458                 int iKeepX = Console.GetRawCursorX();
00459                 int iKeepY = Console.GetRawCursorY();
00460                 if (iParam[0] > Console.GetWidth())
00461                     iParam[0] = Console.GetWidth(); // up to the end of line
00462                 for ( int i = 1; i <= iParam[0]; i++ )
00463                     Console.WriteString(" ", 1);
00464                 Console.SetRawCursorPosition(iKeepX , iKeepY);
00465                 break;
00466             }
00467         // Go back p tab stops
00468         // Added by I.Ioannou 06 April, 1997
00469         // Implemented by Paul Brannan, 4/13/2000
00470         case 'Z':
00471             {
00472                 int x = Console.GetCursorX();
00473                 for(int j = 0; x > 0 && j < iParam[0]; j++)
00474                     while(x > 0 && tab_stops[j] == tab_stops[x]) x--;
00475                 Console.SetCursorPosition(x, Console.GetCursorY());
00476             }
00477             break;
00478         // Get Terminal ID
00479         case 'c':
00480             {
00481                 const char* szTerminalId = GetTerminalID();
00482                 Network.WriteString(szTerminalId, strlen(szTerminalId));
00483                 break;
00484             }
00485         // TITUS++ 2. November 1998: Repeat Character.
00486         case 'b':
00487             // isprint may be causing problems (Paul Brannan 3/27/99)
00488             // if ( isprint(last_char) ) {
00489                 char    buf[150];       // at most 1 line (max 132 chars)
00490 
00491                 if ( iParam[0] > 149 ) iParam[0] = 149;
00492                 memset(buf, last_char, iParam[0]);
00493                 buf[iParam[0]] = 0;
00494                 if ( fast_write )
00495                     Console.WriteStringFast(buf, iParam[0]);
00496                 else
00497                     Console.WriteString(buf, iParam[0]);
00498             // } /* IF */
00499         break;
00500         // Go to line p
00501         // Added by I.Ioannou 06 April, 1997
00502         case 'd':
00503             if (iCurrentParam < 1)          // Alter Default
00504                 iParam[0] = 0;
00505             // this was backward, and we should subtract 1 from y
00506             // (Paul Brannan 5/27/98)
00507             ConSetCursorPos(Console.GetCursorX(), iParam[0] - 1);
00508             break;
00509         // iBCS2 tab erase
00510         // Added by I.Ioannou 06 April, 1997
00511         case 'g':
00512             if (iCurrentParam < 1)          // Alter Default
00513                 iParam[0] = 0;
00514             switch (iParam[0]) {
00515                 case 0:
00516                     {
00517                         // Clear the horizontal tab stop at the current active position
00518                         for(int j = 0; j < MAX_TAB_POSITIONS; j++) {
00519                             int x = Console.GetCursorX();
00520                             if(tab_stops[j] == x) tab_stops[j] = tab_stops[x + 1];
00521                         }
00522                     }
00523                     break;
00524                 case 2:
00525                     // I think this might be "set as default?"
00526                     break;
00527                 case 3:
00528                     {
00529                         // Clear all tab stops
00530                         for(int j = 0; j < MAX_TAB_POSITIONS; j++)
00531                             tab_stops[j] = -1;
00532                     }
00533                     break;
00534             }
00535             break;
00536         // Set extended mode
00537         case 'h':
00538             {
00539                 for (int i = 0; i < iCurrentParam; i++) {
00540                     // Changed to a switch statement (Paul Brannan 5/27/98)
00541                     if(flag & FLAG_QMARK) {
00542                         switch(iParam[i]) {
00543                             case 1: // App cursor keys
00544                                 KeyTrans.set_ext_mode(APP_KEY);
00545                                 break;
00546                             case 2: // VT102 mode
00547                                 vt52_mode = 0;
00548                                 KeyTrans.unset_ext_mode(APP2_KEY);
00549                                 break;
00550                             case 3: // 132 columns
00551                                 if(ini.get_wide_enable()) {
00552                                     Console.SetWindowSize(132, -1);
00553                                 }
00554                                 break;
00555                             case 4: // smooth scrolling
00556                                 break;
00557                             case 5: // Light background
00558                                 Console.Lightbg();
00559                                 break;
00560                             case 6: // Stay in margins
00561                                 ignore_margins = 0;
00562                                 break;
00563                             case 7:
00564                                 Console.setLineWrap(true);
00565                                 break;
00566                             case 8: // Auto-repeat keys
00567                                 break;
00568                             case 18: // Send FF to printer
00569                                 break;
00570                             case 19: // Entire screen legal for printer
00571                                 break;
00572                             case 25: // Visible cursor
00573                                 break;
00574                             case 66: // Application numeric keypad
00575                                 break;
00576                             default:
00577 #ifdef DEBUG
00578                                 Console.Beep();
00579 #endif
00580                                 break;
00581                         }
00582                     } else {
00583                         switch(iParam[i]) {
00584                             case 2: // Lock keyboard
00585                                 break;
00586                             case 3: // Act upon control codes (PB 12/5/98)
00587                                 print_ctrl = 0;
00588                                 break;
00589                             case 4: // Set insert mode
00590                                 Console.InsertMode(1);
00591                                 break;
00592                             case 12: // Local echo off
00593                                 break;
00594                             case 20: // Newline sends cr/lf
00595                                 KeyTrans.set_ext_mode(APP4_KEY);
00596                                 newline_mode = true;
00597                                 break;
00598                             default:
00599 #ifdef DEBUG
00600                                 Console.Beep();
00601 #endif
00602                                 break;
00603                         }
00604                     }
00605                 }
00606             }
00607             break;
00608         // Print Screen
00609         case 'i':
00610             if (iCurrentParam < 1)
00611                 iParam[0]=0;
00612             switch (iParam[0]){
00613                 case 0: break; // Print Screen
00614                 case 1: break; // Print Line
00615                 // Added I.Ioannou 06 April, 1997
00616                 case 4:
00617                     // Stop Print Log
00618                     InPrintMode = 0;
00619                     if ( printfile != NULL )
00620                         fclose(printfile);
00621                     break;
00622                 case 5:
00623                     // Start Print Log
00624                     printfile = fopen(ini.get_printer_name(), "ab");
00625                     if (printfile != NULL) InPrintMode = 1;
00626                     break;
00627             }
00628             break;
00629         // Unset extended mode
00630         case 'l':
00631             {
00632                 for (int i = 0; i < iCurrentParam; i++) {
00633                     // Changed to a switch statement (Paul Brannan 5/27/98)
00634                     if(flag & FLAG_QMARK) {
00635                         switch(iParam[i]) {
00636                             case 1: // Numeric cursor keys
00637                                 KeyTrans.unset_ext_mode(APP_KEY);
00638                                 break;
00639                             case 2: // VT52 mode
00640                                 vt52_mode = 1;
00641                                 KeyTrans.set_ext_mode(APP2_KEY);
00642                                 break;
00643                             case 3: // 80 columns
00644                                 if(ini.get_wide_enable()) {
00645                                     Console.SetWindowSize(80, -1);
00646                                 }
00647                                 break;
00648                             case 4: // jump scrolling
00649                                 break;
00650                             case 5: // Dark background
00651                                 Console.Darkbg();
00652                                 break;
00653                             case 6: // Ignore margins
00654                                 ignore_margins = 1;
00655                                 break;
00656                             case 7:
00657                                 Console.setLineWrap(false);
00658                                 break;
00659                             case 8: // Auto-repeat keys
00660                                 break;
00661                             case 19: // Only send scrolling region to printer
00662                                 break;
00663                             case 25: // Invisible cursor
00664                                 break;
00665                             case 66: // Numeric keypad
00666                                 break;
00667                             default:
00668 #ifdef DEBUG
00669                                 Console.Beep();
00670 #endif
00671                                 break;
00672                         }
00673                     } else {
00674                         switch(iParam[i]) {
00675                             case 2: // Unlock keyboard
00676                                 break;
00677                             case 3: // Display control codes (PB 12/5/98)
00678                                 print_ctrl = 1;
00679                                 break;
00680                             case 4: // Set overtype mode
00681                                 Console.InsertMode(0);
00682                                 break;
00683                             case 12: // Local echo on
00684                                 break;
00685                             case 20: // sends lf only
00686                                 KeyTrans.unset_ext_mode(APP4_KEY);
00687                                 newline_mode = false;
00688                                 break;
00689                             default:
00690 #ifdef DEBUG
00691                                 Console.Beep();
00692 #endif
00693                                 break;
00694                         }
00695                     }
00696                 }
00697             }
00698             break;
00699         // Set color
00700         case 'm':
00701             if(missing_param) Console.Normal();
00702             if(iCurrentParam == 0) {
00703                 Console.Normal();
00704             } else {
00705                 for(int i = 0; i < iCurrentParam; i++)
00706                     ConSetAttribute(iParam[i]);
00707             }
00708             break;
00709         // report cursor position Row X Col
00710         case 'n':
00711             if (iCurrentParam == 1 && iParam[0]==5) {
00712                 // report the cursor position
00713                 Network.WriteString("\x1B[0n", 6);
00714                 break;
00715             }
00716             if (iCurrentParam == 1 && iParam[0]==6){
00717                 // report the cursor position
00718                 // The cursor position needs to be sent as a single string
00719                 // (Paul Brannan 6/27/98)
00720                 char szCursorReport[40] = "\x1B[";
00721 
00722                 itoa(Console.GetCursorY() + 1,
00723                     &szCursorReport[strlen(szCursorReport)], 10);
00724                 strcat(szCursorReport, ";");
00725                 itoa(Console.GetCursorX() + 1,
00726                     &szCursorReport[strlen(szCursorReport)], 10);
00727                 strcat(szCursorReport, "R");
00728 
00729                 Network.WriteString(szCursorReport, strlen(szCursorReport));
00730 
00731             }
00732             break;
00733         // Miscellaneous weird sequences (Paul Brannan 6/27/98)
00734         case 'p':
00735             // Set conformance level
00736             if(flag & FLAG_QUOTE) {
00737                 break;
00738             }
00739             // Soft terminal reset
00740             if(flag & FLAG_EXCLAM) {
00741                 break;
00742             }
00743             // Report mode settings
00744             if(flag & FLAG_DOLLAR) {
00745                 break;
00746             }
00747             break;
00748         // Scroll Screen
00749         case 'r':
00750             if (iCurrentParam < 1) {
00751                 // Enable scrolling for entire display
00752                 Console.SetScroll(-1, -1);
00753                 break;
00754             }
00755             if (iCurrentParam >1) {
00756                 // Enable scrolling from row1 to row2
00757                 Console.SetScroll(iParam[0] - 1, iParam[1] - 1);
00758                 // If the cursor is outside the scrolling range, fix it
00759                 // (Paul Brannan 6/26/98)
00760                 // if(Console.GetRawCursorY() < iParam[0] - 1) {
00761                 //  Console.SetRawCursorPosition(Console.GetCursorX(),
00762                 //      iParam[0] - 1);
00763                 // }
00764                 // if(Console.GetRawCursorY() > iParam[1] - 1) {
00765                 //  Console.SetRawCursorPosition(Console.GetCursorX(),
00766                 //      iParam[1] - 1);
00767                 // }
00768             }
00769             // Move the cursor to the home position (Paul Brannan 12/2/98)
00770             Console.SetCursorPosition(0, 0);
00771             break;
00772         // Save cursor position
00773         case 's':
00774             SaveCurY(Console.GetRawCursorY());
00775             SaveCurX(Console.GetRawCursorX());
00776             break;
00777         // Restore cursor position
00778         case 'u':
00779             Console.SetRawCursorPosition(iSavedCurX, iSavedCurY);
00780             break;
00781         // DEC terminal report (Paul Brannan 6/28/98)
00782         case 'x':
00783             if(iParam[0])
00784                 Network.WriteString("\033[3;1;1;128;128;1;0x", 20);
00785             else
00786                 Network.WriteString("\033[2;1;1;128;128;1;0x", 20);
00787             break;
00788         default:
00789 #ifdef DEBUG
00790             Console.Beep();
00791 #endif
00792             break;
00793     }
00794 
00795     return pszBuffer;
00796 }
00797 
00798 #ifdef MTE_SUPPORT
00799 // Added by Frediano Ziglio, 5/31/2000
00800 // MTE extension
00801 // initially copied from ParseEscapeANSI
00802 char* TANSIParser::ParseEscapeMTE(char* pszBuffer, char* pszBufferEnd)
00803 {
00804     //      The buffer contains something like <ESC>~pA
00805     //      where p is an optional decimal number specifying the count by which the
00806     //      appropriate action should take place.
00807     //      The pointer pszBuffer points us to the p, <ESC> and ~ are
00808     //      already 'consumed'
00809     //      TITUS: Simplification of the code: Assume default count of 1 in case
00810     //      there are no parameters.
00811     char tmpc;
00812     const int nParam = 10;  // Maximum number of parameters
00813     int     iParam[nParam] = {1, 0, 0, 0, 0};       // Assume 1 parameter, Default 1
00814     int iCurrentParam = 0;
00815     char sRepeat[2];
00816 
00817     // Get parameters from escape sequence.
00818     while ((tmpc = *pszBuffer) <= '?') {
00819         if(tmpc < '0' || tmpc > '9') {
00820             // Check for parameter delimiter.
00821             if(tmpc == ';') {
00822                 pszBuffer++;
00823                 continue;
00824             }
00825             pszBuffer++;
00826         }
00827 
00828         //  Got Numerical Parameter.
00829         iParam[iCurrentParam] = strtoul(pszBuffer, &pszBuffer, 10);
00830         if (iCurrentParam < nParam)
00831             iCurrentParam++;
00832     }
00833 
00834     //~~~ TITUS: Apparently the digit is optional (look at termcap or terminfo)
00835     // So: If there is no digit, assume a count of 1
00836 
00837     switch ((unsigned char)*pszBuffer++) {
00838         case 'A':
00839             // set colors
00840             if (iCurrentParam < 2 )
00841                 break;
00842             if (iParam[0] <= 15 && iParam[1] <= 15)
00843                 Console.SetAttrib( (iParam[1] << 4) | iParam[0] );
00844             break;
00845 
00846         case 'R':
00847             // define region
00848             mteRegionXF = -1;
00849             if (iCurrentParam < 2 )
00850                 break;
00851             mteRegionXF = iParam[1]-1;
00852             mteRegionYF = iParam[0]-1;
00853             break;
00854 
00855         case 'F':
00856             // fill with char
00857             {
00858                 if (mteRegionXF == -1 || iCurrentParam < 1)
00859                     break;
00860                 sRepeat[0] = (char)iParam[0];
00861                 sRepeat[1] = '\0';
00862                 int xi = Console.GetCursorX(),yi = Console.GetCursorY();
00863                 int xf = mteRegionXF;
00864                 int yf = mteRegionYF;
00865                 mteRegionXF = -1;
00866                 for(int y=yi;y<=yf;++y)
00867                 {
00868                     Console.SetCursorPosition(xi,y);
00869                     for(int x=xi;x<=xf;++x)
00870 
00871                         Console.WriteStringFast(sRepeat,1);
00872                 }
00873             }
00874             break;
00875 
00876         case 'S':
00877             // Scroll region
00878             {
00879                 if (mteRegionXF == -1 || iCurrentParam < 2)
00880                     break;
00881                 int /*x = Console.GetCursorX(),*/y = Console.GetCursorY();
00882                 // int xf = mteRegionXF;
00883                 int yf = mteRegionYF;
00884                 mteRegionXF = -1;
00885                 // !!! don't use x during scroll
00886                 int diff = (iParam[0]-1)-y;
00887                 if (diff<0)
00888                     Console.ScrollDown(y-1,yf,diff);
00889                 else
00890                     Console.ScrollDown(y,yf+1,diff);
00891             }
00892             break;
00893             // Meridian main version ??
00894         case 'x':
00895             // disable echo and line mode
00896             Network.set_local_echo(0);
00897             Network.set_line_mode(0);
00898             // Meridian Server handle cursor itself
00899             Console.SetCursorSize(0);
00900             break;
00901             // query ??
00902         case 'Q':
00903             if (iParam[0] == 1)
00904                 Network.WriteString("\033vga.",5);
00905             break;
00906         default:
00907 #ifdef DEBUG
00908             Console.Beep();
00909 #endif
00910             break;
00911     }
00912 
00913     return pszBuffer;
00914  }
00915 #endif
00916 
00917 char* TANSIParser::ParseEscape(char* pszBuffer, char* pszBufferEnd) {
00918     char *pszChar;
00919 
00920     // Check if we have enough characters in buffer.
00921     if ((pszBufferEnd - pszBuffer) < 2)
00922         return pszBuffer;
00923 
00924     //  I.Ioannou 04 Sep 1997
00925     // there is no need for pszBuffer++; after each command
00926 
00927     // Decode the command.
00928     pszBuffer++;
00929 
00930     switch (*pszBuffer++) {
00931         case 'A': // Cursor up
00932             Console.MoveCursorPosition(0, -1);
00933             break;
00934         // Cursor down
00935         case 'B':
00936             Console.MoveCursorPosition(0, 1);
00937             break;
00938         // Cursor right
00939         case 'C':
00940             Console.MoveCursorPosition(1, 0);
00941             break;
00942         // LF *or* cursor left (Paul Brannan 6/27/98)
00943         case 'D':
00944             if(vt52_mode)
00945                 Console.MoveCursorPosition(-1, 0);
00946             else
00947                 Console.index();
00948             break;
00949         // CR/LF (Paul Brannan 6/26/98)
00950         case 'E':
00951             Console.WriteCtrlString("\r\n", 2);
00952             break;
00953         // Special graphics char set (Paul Brannan 6/27/98)
00954         case 'F':
00955             Charmap.setmap('0');
00956             break;
00957         // ASCII char set (Paul Brannan 6/27/98)
00958         case 'G':
00959             Charmap.setmap('B');
00960             break;
00961         // Home cursor/tab set
00962         case 'H':
00963             if(ini.get_vt100_mode()) {
00964                 int x = Console.GetCursorX();
00965                 if(x != 0) {
00966                     int t = tab_stops[x - 1];
00967                     for(int j = x - 1; j >= 0 && tab_stops[j] == t; j--)
00968                         tab_stops[j] = x;
00969                 }
00970             } else {
00971                 //  I.Ioannou 04 Sep 1997 (0,0) not (1,1)
00972                 ConSetCursorPos(0, 0);
00973             }
00974             break;
00975         // Reverse line feed (Paul Brannan 6/27/98)
00976         // FIX ME!!!  reverse_index is wrong to be calling here
00977         // (Paul Brannan 12/2/98)
00978         case 'I':
00979             Console.reverse_index();
00980             break;
00981         // Erase end of screen
00982         case 'J':
00983             Console.ClearEOScreen();
00984             break;
00985         // Erase EOL
00986         case 'K':
00987             Console.ClearEOLine();
00988             break;
00989         // Scroll Up one line //Reverse index
00990         case 'M':
00991             Console.reverse_index();
00992             break;
00993         // Direct cursor addressing
00994         case 'Y':
00995             if ((pszBufferEnd - pszBuffer) >= 2){
00996                 // if we subtract '\x1F', then we may end up with a negative
00997                 // cursor position! (Paul Brannan 6/26/98)
00998                 ConSetCursorPos(pszBuffer[1] - ' ', pszBuffer[0] - ' ');
00999                 pszBuffer+=2;
01000             } else {
01001                 pszBuffer--; // Paul Brannan 6/26/98
01002             }
01003             break;
01004         // Terminal ID Request
01005         case 'Z':
01006             {
01007                 const char* szTerminalId = GetTerminalID();
01008                 Network.WriteString(szTerminalId, strlen(szTerminalId));
01009                 break;
01010             }
01011         // reset terminal to defaults
01012         case 'c':
01013             ResetTerminal();
01014             break;
01015         // Enter alternate keypad mode
01016         case '=':
01017             KeyTrans.set_ext_mode(APP3_KEY);
01018             break;
01019         // Exit alternate keypad mode
01020         case '>':
01021             KeyTrans.unset_ext_mode(APP3_KEY);
01022             break;
01023         // Enter ANSI mode
01024         case '<':
01025             KeyTrans.unset_ext_mode(APP2_KEY); // exit vt52 mode
01026             break;
01027         // Graphics processor on (See note 3)
01028         case '1':
01029             break;
01030         // Line size commands
01031         case '#':        //Line size commands
01032             // (Paul Brannan 6/26/98)
01033             if(pszBuffer < pszBufferEnd) {
01034                 switch(*pszBuffer++) {
01035                 case '3': break; // top half of a double-height line
01036                 case '4': break; // bottom half of a double-height line
01037                 case '6': break; // current line becomes double-width
01038                 case '8': Console.ClearScreen('E'); break;
01039                 }
01040             } else {
01041                 pszBuffer--;
01042             }
01043             break;
01044         // Graphics processor off (See note 3)
01045         case '2':
01046             break;
01047         // Save cursor and attribs
01048         case '7':
01049             SaveCurY(Console.GetRawCursorY());
01050             SaveCurX(Console.GetRawCursorX());
01051             iSavedAttributes = Console.GetAttrib();
01052             break;
01053             // Restore cursor position and attribs
01054         case '8':
01055             Console.SetRawCursorPosition(iSavedCurX, iSavedCurY);
01056             Console.SetAttrib(iSavedAttributes);
01057             break;
01058         // Set G0 map (Paul Brannan 6/25/98)
01059         case '(':
01060             if (pszBuffer < pszBufferEnd) {
01061                 map_G0 = *pszBuffer;
01062                 if(current_map == 0) Charmap.setmap(map_G0);
01063                 pszBuffer++;
01064             } else {
01065                 pszBuffer--;
01066             }
01067             break;
01068         // Set G1 map (Paul Brannan 6/25/98)
01069         case ')':
01070             if (pszBuffer < pszBufferEnd) {
01071                 map_G1 = *pszBuffer;
01072                 if(current_map == 1) Charmap.setmap(map_G1);
01073                 pszBuffer++;
01074             } else {
01075                 pszBuffer--;
01076             }
01077             break;
01078         // This doesn't do anything, as far as I can tell, but it does take
01079         // a parameter (Paul Brannan 6/27/98)
01080         case '%':
01081             if (pszBuffer < pszBufferEnd) {
01082                 pszBuffer++;
01083             } else {
01084                 pszBuffer--;
01085             }
01086             break;
01087         // ANSI escape sequence
01088         case '[':
01089             // Check if we have whole escape sequence in buffer.
01090             // This should not be isalpha anymore (Paul Brannan 9/1/98)
01091             pszChar = pszBuffer;
01092             while ((pszChar < pszBufferEnd) && (*pszChar <= '?'))
01093                 pszChar++;
01094             if (pszChar == pszBufferEnd)
01095                 pszBuffer -= 2;
01096             else
01097                 pszBuffer = ParseEscapeANSI(pszBuffer, pszBufferEnd);
01098             break;
01099 #ifdef MTE_SUPPORT
01100         case '~':
01101             // Frediano Ziglio, 5/31/2000
01102             // Meridian Terminal Emulator extension
01103             // !!! same as ANSI
01104             // !!! should put in MTE procedure
01105             pszChar = pszBuffer;
01106             while ((pszChar < pszBufferEnd) && (*pszChar <= '?'))
01107                 pszChar++;
01108             if (pszChar == pszBufferEnd)
01109                 pszBuffer -= 2;
01110             else
01111                 pszBuffer = ParseEscapeMTE(pszBuffer, pszBufferEnd);
01112             break;
01113 #endif
01114         default:
01115 #ifdef DEBUG
01116             Console.Beep();
01117 #endif
01118             break;
01119     }
01120 
01121     return pszBuffer;
01122 }
01123 
01124 // This function now only parses the ANSI buffer and does not do anything
01125 // with IAC sequences.  That code has been moved to TTelHndl.cpp.
01126 // The scroller update routines have been moved to TScroll.cpp.
01127 // (Paul Brannan 6/15/98)
01128 char* TANSIParser::ParseBuffer(char* pszHead, char* pszTail){
01129     // copy into ANSI buffer
01130     char * pszResult;
01131 
01132     // Parse the buffer for ANSI or display
01133     while (pszHead < pszTail) {
01134         if(!ini.get_output_redir()) {
01135             pszResult = ParseANSIBuffer(pszHead, pszTail);
01136         } else {
01137             // Output is being redirected
01138             if(ini.get_strip_redir()) {
01139                 // Skip the WriteFile() altogether and pass the buffer to a filter
01140                 // Mark Miesfield 09/24/2000
01141                 pszResult = PrintGoodChars(pszHead, pszTail);
01142             } else {
01143                 DWORD Result;
01144                 // Paul Brannan 7/29/98
01145                 // Note that this has the unforunate effect of printing out
01146                 // NULL (ascii 0) characters onto the screen
01147                 if (!WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), pszHead,
01148                     pszTail - pszHead, &Result, NULL)) pszResult = pszHead;
01149                 pszResult = pszHead + Result;
01150             }
01151         }
01152         if (dumpfile)
01153             fwrite( pszHead, sizeof (char), pszResult-pszHead, dumpfile);
01154         if(ini.get_scroll_enable()) Scroller.update(pszHead, pszResult);
01155         if (pszResult == pszHead) break;
01156         pszHead = pszResult;
01157     }
01158     // return the new head to the buffer
01159     return pszHead;
01160 }
01161 
01162 // A simple routine to strip ANSI sequences
01163 // This isn't perfect, but it does an okay job (Paul Brannan 7/5/98)
01164 // Fixed a line counting bug (Paul Brannan 12/4/98)
01165 int TANSIParser::StripBuffer(char* pszHead, char* pszTail, int width) {
01166     int lines = 0, c = 0;
01167     char *pszBuf = pszHead;
01168 
01169     while(pszHead < pszTail) {
01170         if(iscntrl(*pszHead)) {
01171             switch(*(pszHead++)) {
01172             case 8:
01173             case 127:
01174                 if(c>0) {
01175                     if(!(c%width)) lines--;
01176                     c--;
01177                     pszBuf--;
01178                 }
01179                 break;
01180             case 10: lines++;
01181             case 13:
01182                 *(pszBuf++) = *(pszHead - 1);
01183                 c = 0;
01184                 break;
01185             case 27:
01186                 switch(*(pszHead++)) {
01187                 case 'Y': pszHead += 2; break;
01188                 case '#':
01189                 case '(':
01190                 case ')':
01191                 case '%': pszHead++; break;
01192                 case '[':
01193                     while((pszHead < pszTail) && (*pszHead < '?'))
01194                         pszHead++;
01195                     pszHead++;
01196                     break;
01197                 }
01198             }
01199         } else {
01200             *(pszBuf++) = *(pszHead++);
01201             c++;
01202         }
01203         if(c != 0 && !(c%width))
01204             lines++;
01205     }
01206 
01207     // Fill in the end of the buffer with blanks
01208     while(pszBuf <= pszTail) *pszBuf++ = ' ';
01209 
01210     return lines;
01211 }
01212 
01213 char* TANSIParser::ParseANSIBuffer(char* pszBuffer, char* pszBufferEnd)
01214 {
01215     if(InPrintMode) {
01216         return PrintBuffer(pszBuffer, pszBufferEnd);
01217     }
01218 
01219     unsigned char tmpc = *(unsigned char *)pszBuffer;
01220 
01221     if(tmpc == 27) {
01222         return ParseEscape(pszBuffer, pszBufferEnd);
01223     }
01224 
01225 //  if((fast_write && tmpc < 32) ||
01226 //      !print_ctrl && (tmpc < 32 || (EightBit_Ansi &&
01227 //      (tmpc > 128 && tmpc < 128 + ' ')))) {
01228 
01229     // We shouldn't print ctrl characters when fast write is enabled
01230     // and ctrl chars are disabled (Paul Brannan 9/1/98)
01231     if(tmpc < 32) {
01232         // From the Linux kernel (Paul Brannan 12/5/98):
01233         /* A bitmap for codes <32. A bit of 1 indicates that the code
01234          * corresponding to that bit number invokes some special action
01235          * (such as cursor movement) and should not be displayed as a
01236          * glyph unless the disp_ctrl mode is explicitly enabled.
01237          */
01238         const long CTRL_ACTION = 0x0d00ff81;
01239         const long CTRL_ALWAYS = 0x0800f501;
01240         if(!(((print_ctrl?CTRL_ALWAYS:CTRL_ACTION)>>tmpc)&1)) {
01241 
01242             Console.WriteString((char *)&tmpc, 1);
01243             pszBuffer++;
01244             return pszBuffer;
01245         }
01246 
01247         switch (tmpc) {
01248         case 0:
01249             pszBuffer++;
01250             break;
01251 
01252         // I.Ioannou 5/30/98
01253         case 7:
01254             Console.Beep();
01255             pszBuffer++;
01256             break;
01257 
01258         // destructive backspace
01259         case 8:
01260             // Added option for destructive backspace (Paul Brannan 5/13/98)
01261             // Changed to ConWriteCtrlString so that the cursor position can be
01262             // updated (Paul Brannan 5/25/98)
01263             if(ini.get_dstrbksp()) {
01264                 Console.WriteCtrlChar('\b');
01265                 Console.WriteString(" ", 1);
01266                 Console.WriteCtrlChar('\b');
01267             }
01268             else Console.WriteCtrlChar('\b');
01269             pszBuffer++;
01270             break;
01271 
01272         // horizontal tab
01273         case 9:
01274             {
01275                 pszBuffer++;
01276                 int x = Console.GetCursorX();
01277                 if(x != -1)
01278                     Console.SetCursorPosition(tab_stops[x], Console.GetCursorY());
01279             }
01280             break;
01281 
01282         // Line Feed Char
01283         case 10:
01284             // Test for local echo (Paul Brannan 8/25/98)
01285             if(Network.get_local_echo() || newline_mode) // &&
01286                 Console.WriteCtrlChar('\x0d');
01287             Console.WriteCtrlChar('\x0a');
01288             pszBuffer++;
01289             break;
01290 
01291         // form feed
01292         case 12:
01293             pszBuffer++;
01294             Console.ClearScreen();
01295             Console.SetRawCursorPosition(Console.GetCursorX(), 1); // changed fm 1
01296             break;
01297 
01298         case 13:
01299             Console.WriteCtrlChar('\x0d');
01300             pszBuffer++;
01301 
01302             break;
01303 
01304         case 14:  // shift out of alternate chararcter set
01305             pszBuffer++;
01306             Charmap.setmap(map_G1); // Paul Brannan 6/25/98
01307             current_map = 1;
01308             break;
01309 
01310         case 15:  // shift in
01311             pszBuffer++;
01312             Charmap.setmap(map_G0); // Paul Brannan 6/25/98
01313             current_map = 0;
01314             break;
01315 
01316         // Paul Brannan 9/1/98 - Is this okay?
01317         default:
01318             pszBuffer++;
01319         }
01320 
01321         return pszBuffer;
01322     }
01323 
01324     //  added by I.Ioannou 06 April, 1997
01325     //  In 8 bit systems the server may send 0x9b instead of ESC[
01326     //  Well, this will produce troubles in Greek 737 Code page
01327     //  which uses 0x9b as the small "delta" - and I thing that there
01328     //  is another European country with the same problem.
01329     //  If we have to stay 8-bit clean we may have to
01330     //  give the ability of ROM characters (ESC[11m),
01331     //  for striped 8'th bit (ESC[12m) as SCO does,
01332     //  or a parameter at compile (or run ?) time.
01333     // We now check for a flag in the ini file (Paul Brannan 5/13/98)
01334     // We also handle any 8-bit ESC sequence (Paul Brannan 6/28/98)
01335     if(ini.get_eightbit_ansi() && (tmpc > 128 && tmpc < 128 + ' ')) {
01336         // There's a chance the sequence might not parse.  If this happens
01337         // then pszBuffer will be one character too far back, since
01338         // ParseEscape is expecting two characters, not one.
01339         // In that case we must handle it.
01340         char *pszCurrent = pszBuffer;
01341         pszBuffer = ParseEscape(pszBuffer, pszBufferEnd);
01342         if(pszBuffer < pszCurrent) pszBuffer = pszCurrent;
01343     }
01344 
01345     char* pszCurrent = pszBuffer + 1;
01346     // I.Ioannou 04 Sep 1997 FIXME with ESC[11m must show chars < 32
01347     // Fixed (Paul Brannan 6/28/98)
01348     while ((pszCurrent < pszBufferEnd) && (!iscntrl(*pszCurrent))) {
01349         // I.Ioannou 04 Sep 1997 strip on high bit
01350         if ( (inGraphMode) && (*pszCurrent > (char)32) )
01351             *pszCurrent |= 0x80 ;
01352         pszCurrent++;
01353     }
01354 
01355     // Note that this may break dumpfiles slightly.
01356     // If 'B' is set to anything other than ASCII, this will cause problems
01357     // (Paul Brannan 6/28/98)
01358     if(current_map != 'B' && Charmap.enabled)
01359         Charmap.translate_buffer(pszBuffer, pszCurrent);
01360 
01361     last_char = *(pszCurrent-1);    // TITUS++: Remember last char
01362 
01363     if(fast_write) {
01364         pszBuffer += Console.WriteStringFast(pszBuffer,
01365             pszCurrent - pszBuffer);
01366     } else {
01367         pszBuffer += Console.WriteString(pszBuffer,
01368             pszCurrent - pszBuffer);
01369     }
01370 
01371     return pszBuffer;
01372 }
01373 
01374 // Added by I.Ioannou 06 April, 1997
01375 // Print the buffer until you reach ESC[4i
01376 char* TANSIParser::PrintBuffer(char* pszBuffer, char* pszBufferEnd) {
01377     // Check if we have enough characters in buffer.
01378     if ((pszBufferEnd - pszBuffer) < 4)
01379         return pszBuffer;
01380     char *tmpChar;
01381 
01382     tmpChar = pszBuffer;
01383     if ( *tmpChar == 27 ) {
01384         tmpChar++;
01385         if ( *tmpChar == '[' ) {
01386             tmpChar++;
01387             if ( *tmpChar == '4' ) {
01388                 tmpChar++;
01389                 if ( *tmpChar == 'i' ) {
01390                     InPrintMode = 0; // Stop Print Log
01391                     if ( printfile != NULL )
01392                         fclose(printfile);
01393                     pszBuffer += 4;
01394                     return pszBuffer;
01395                 }
01396             }
01397         }
01398     }
01399 
01400     if (printfile != NULL) {
01401         fputc( *pszBuffer, printfile);
01402         pszBuffer++;
01403     } else
01404         InPrintMode = 0;
01405 
01406     return pszBuffer;
01407 }
01408 
01409 /* - PrintGoodChars( pszHead, pszTail ) - - - - - - - - - - - - - - - - - - -
01410 -*
01411 
01412   Mark Miesfield 09/24/2000
01413 
01414   Prints the characters in a buffer, from the specified head to the specified
01415   tail, to standard out, skipping any control characters or ANSI escape
01416   sequences.
01417 
01418   Parameters on entry:
01419     pszHead  ->  Starting point in buffer.
01420 
01421     pszTail  ->  Ending point in buffer.
01422 
01423   Returns:
01424     Pointer to the first character in the buffer that was not output to
01425     standard out.  (Since no error checking is done, this is in effect
01426     pszTail.)
01427 
01428   Side Effects:
01429     None.
01430 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
01431 */
01432 char * TANSIParser::PrintGoodChars( char * pszHead, char * pszTail )  {
01433 
01434   while ( pszHead < pszTail )  {
01435     if ( iscntrl( *pszHead ) )  {
01436       switch ( *(pszHead++) )  {
01437         case 10 :
01438           putc( 10, stdout );
01439           break;
01440 
01441         case 13 :
01442           putc( 13, stdout );
01443           break;
01444 
01445         case 27:
01446           switch ( *(pszHead++) )  {
01447             case 'Y':
01448               pszHead += 2;
01449               break;
01450 
01451             case '#':
01452             case '(':
01453             case ')':
01454             case '%': pszHead++; break;
01455             case '[':
01456               while ( (pszHead < pszTail) && (*pszHead < '?') )
01457                 pszHead++;
01458               pszHead++;
01459               break;
01460 
01461             default :
01462               break;
01463           }
01464           break;
01465 
01466         default :
01467           break;
01468       }
01469     }
01470     else
01471       putc( *(pszHead++), stdout );
01472   }
01473   return ( pszTail );
01474 }
01475 // End of function:  PrintGoodChars( pszHead, pszTail )

Generated on Sat May 26 2012 04:16:11 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.