Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenansiprsr.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
1.7.6.1
|