Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364/////////////////////////////////////////////////////////////////////////////////Telnet Win32 : an ANSI telnet client.//Copyright (C) 1998-2000 Paul Brannan//Copyright (C) 1998 I.Ioannou//Copyright (C) 1997 Brad Johnson////This program is free software; you can redistribute it and/or//modify it under the terms of the GNU General Public License//as published by the Free Software Foundation; either version 2//of the License, or (at your option) any later version.////This program is distributed in the hope that it will be useful,//but WITHOUT ANY WARRANTY; without even the implied warranty of//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the//GNU General Public License for more details.////You should have received a copy of the GNU General Public License//along with this program; if not, write to the Free Software//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.////I.Ioannou//roryt@hol.gr/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////// Module: tscroll.cpp//// Contents: Telnet Handler//// Product: telnet//// Revisions: Dec. 5, 1998 Paul Brannan <pbranna@clemson.edu>// June 15, 1998 Paul Brannan//// This is code originally from tnclass.cpp and ansiprsr.cpp/////////////////////////////////////////////////////////////////////////////////
#include "precomp.h"
enum { HEX, DUMP, DUMPB, TEXTB,};
int DummyStripBuffer(char *start, char *end, int width) {return 0;}
TScroller::TScroller(TMouse &M, int size) : Mouse(M) { iScrollSize = size; pcScrollData = new char[iScrollSize]; iScrollEnd = 0; iPastEnd = 0; memset(pcScrollData, ' ', iScrollSize);
if(stricmp(ini.get_scroll_mode(), "hex") == 0) iDisplay = HEX; else if(stricmp(ini.get_scroll_mode(), "dump") == 0) iDisplay = DUMP; else if(stricmp(ini.get_scroll_mode(), "dumpb") == 0) iDisplay = DUMPB; else if(stricmp(ini.get_scroll_mode(), "text") == 0) iDisplay = TEXTB; else iDisplay = DUMP;
strip = &DummyStripBuffer;}
TScroller::~TScroller() { delete[] pcScrollData;}
void TScroller::init(stripfunc *s) { strip = s;}
// Fixed update of circular buffer (Paul Brannan 12/4/98)// Note: iScrollEnd is one character beyond the endvoid TScroller::update(const char *pszHead, const char *pszTail) { if ((iScrollEnd)+(pszTail-pszHead) < iScrollSize) { memcpy(&pcScrollData[iScrollEnd], pszHead, pszTail-pszHead); } else if (pszTail-pszHead > iScrollSize) { memcpy(pcScrollData, pszTail-iScrollSize, iScrollSize); iScrollEnd = 0; } else { memcpy(&pcScrollData[iScrollEnd], pszHead, iScrollSize-iScrollEnd); memcpy(&pcScrollData[0], pszHead + (iScrollSize-iScrollEnd), pszTail-pszHead-(iScrollSize-iScrollEnd)); }
// This could probably be optimized better, but it's probably not worth it int temp = iScrollEnd; iScrollEnd = ((iScrollEnd)+(pszTail-pszHead))%iScrollSize; if(iScrollEnd < temp) iPastEnd = 1;}
// Perhaps this should be moved to Tconsole.cpp? (Paul Brannan 6/12/98)static BOOL WriteConsoleOutputCharAndAttribute( HANDLE hConsoleOutput, // handle of a console screen buffer CHAR * lpWriteBuffer, WORD wAttrib, SHORT sX, SHORT sY ){ // we ought to allocate memory before writing to an address (PB 5/12/98) DWORD cWritten; const LPDWORD lpcWritten = &cWritten;
DWORD cWriteCells = strlen(lpWriteBuffer); COORD coordWrite = {sX,sY}; LPWORD lpwAttribute = new WORD[cWriteCells]; for (unsigned int i = 0; i < cWriteCells; i++) lpwAttribute[i] = wAttrib; WriteConsoleOutputAttribute( hConsoleOutput, // handle of a console screen buffer lpwAttribute, // address of buffer to write attributes from cWriteCells, // number of character cells to write to coordWrite, // coordinates of first cell to write to lpcWritten // address of number of cells written to ); WriteConsoleOutputCharacter( hConsoleOutput, // handle of a console screen buffer lpWriteBuffer, // address of buffer to write characters from cWriteCells, // number of character cells to write to coordWrite, // coordinates of first cell to write to lpcWritten // address of number of cells written to ); delete [] lpwAttribute; return 1;}
static void hexify(int x, char *str, int len) { for(int j = len - 1; j >= 0; j--) { str[j] = x % 16; if(str[j] > 9) str[j] += 'A' - 10; else str[j] += '0'; x /= 16; }}
static int setmaxlines(int iDisplay, int iScrollSize, int strippedlines, int con_width) { switch(iDisplay) { case HEX: return(iScrollSize / 16); break; case DUMP: case DUMPB: return(iScrollSize / con_width); break; case TEXTB: return(strippedlines); break; } return 0;}
static void setstatusline(char *szStatusLine, int len, int iDisplay) { memset(szStatusLine, ' ', len); memcpy(&szStatusLine[1], "Scrollback Mode", 15); switch(iDisplay) { case HEX: memcpy(&szStatusLine[len / 2 - 1], "HEX", 3); break; case DUMP: memcpy(&szStatusLine[len / 2 - 2], "DUMP", 4); break; case DUMPB: memcpy(&szStatusLine[len / 2 - 5], "BINARY DUMP", 11); break; case TEXTB: memcpy(&szStatusLine[len / 2 - 2], "TEXT", 4); break; } memcpy(&szStatusLine[len - 6], "READY", 5); szStatusLine[len] = 0;}
void TScroller::ScrollBack(){ char p; int r,c;
// define colors (Paul Brannan 7/5/98) int normal = (ini.get_scroll_bg() << 4) | ini.get_scroll_fg(); // int inverse = (ini.get_scroll_fg() << 4) | ini.get_scroll_bg(); int status = (ini.get_status_bg() << 4) | ini.get_status_fg();
CHAR_INFO* chiBuffer; chiBuffer = newBuffer(); saveScreen(chiBuffer);
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo; GetConsoleScreenBufferInfo(hStdout, &ConsoleInfo);
// Update iScrollBegin -- necessary in case the buffer isn't full yet long iScrollBegin, iScrollLast; if(iPastEnd == 0) { iScrollBegin = 0; iScrollLast = iScrollEnd - 1; } else { iScrollBegin = iScrollEnd; iScrollLast = iScrollSize - 1; }
// Create buffer with ANSI codes stripped // Fixed this to work properly with a circular buffer (PB 12/4/98) char *stripped = new char[iScrollSize]; memcpy(stripped, pcScrollData + iScrollBegin, iScrollSize - iScrollBegin); if(iScrollBegin != 0) memcpy(stripped + (iScrollSize - iScrollBegin), pcScrollData, iScrollBegin - 1); int strippedlines = (*strip)(stripped, stripped + iScrollLast, CON_COLS);
// Calculate the last line of the scroll buffer (Paul Brannan 12/4/98) int maxlines = setmaxlines(iDisplay, iScrollLast + 1, strippedlines, CON_COLS);
// init scroll position int current = maxlines - CON_HEIGHT + 1; if(current < 0) current = 0;
// paint border and info // paint last two lines black on white char * szStatusLine; szStatusLine = new char[CON_WIDTH+2]; setstatusline(szStatusLine, CON_COLS, iDisplay); WriteConsoleOutputCharAndAttribute(hStdout, szStatusLine, status, CON_LEFT, CON_BOTTOM);
// loop while not done BOOL done = FALSE; while (!done){ switch (iDisplay){ case HEX: memset(szStatusLine, ' ', CON_COLS); szStatusLine[8] = ':'; szStatusLine[34] = '-'; for (r = 0; r < CON_HEIGHT; r++) { hexify((r + current) * 16, &szStatusLine[2], 6); for (c = 0; c < 16; c++){ if (c+(16*(r+current)) >= iScrollLast) p = 0; else p = pcScrollData[(c+16*(r+current) + iScrollBegin) % iScrollSize]; hexify((char)p, &szStatusLine[11 + 3*c], 2); if (!iscntrl(p)) { szStatusLine[60 + c] = (char)p; } else { szStatusLine[60 + c] = '.'; } } for(int j = 0; j < 16; j++) { } szStatusLine[CON_COLS] = '\0'; WriteConsoleOutputCharAndAttribute(hStdout, szStatusLine, normal, CON_LEFT, r+CON_TOP); } break; case DUMP: for (r = 0; r < CON_HEIGHT; r++) { for (c = 0; c <= CON_WIDTH; c++) { if (c+((CON_COLS)*(r+current)) >= iScrollLast) p = ' '; else p = pcScrollData[(c+((CON_COLS)*(r+current)) + iScrollBegin) % iScrollSize]; if (!iscntrl(p)) szStatusLine[c] = p; else szStatusLine[c] = '.'; } szStatusLine[c] = '\0'; WriteConsoleOutputCharAndAttribute(hStdout, szStatusLine, normal, CON_LEFT, r+CON_TOP); } break; case DUMPB: for (r = 0; r < CON_HEIGHT; r++) { for (c = 0; c <= CON_WIDTH; c++) { if (c+((CON_COLS)*(r+current)) >= iScrollLast) p = ' '; else p = pcScrollData[ (c+((CON_COLS)*(r+current)) + iScrollBegin) % iScrollSize]; if (p != 0) szStatusLine[c] = p; else szStatusLine[c] = ' '; } szStatusLine[c] = '\0'; WriteConsoleOutputCharAndAttribute(hStdout, szStatusLine, normal, CON_LEFT, r+CON_TOP); } break; case TEXTB: { int ch, lines, x; // Find the starting position for(ch = 0, lines = 0, x = 1; ch < iScrollSize && lines < current; ch++, x++) {
if(stripped[ch] == '\n') lines++; if(stripped[ch] == '\r') x = 1; }
for (r = 0; r < CON_HEIGHT; r++) { memset(szStatusLine, ' ', CON_COLS); for(c = 0; c <= CON_WIDTH; c++) { done = FALSE; if (ch >= iScrollSize) p = ' '; else p = stripped[ch]; switch(p) { case 10: done = TRUE; break; case 13: c = 0; break; default: szStatusLine[c] = p; } ch++; if(done) break; } szStatusLine[CON_COLS] = '\0'; WriteConsoleOutputCharAndAttribute(hStdout, szStatusLine, normal, CON_LEFT, r+CON_TOP); } } break; }
setstatusline(szStatusLine, CON_COLS, iDisplay); WriteConsoleOutputCharAndAttribute(hStdout, szStatusLine, status, CON_LEFT, CON_BOTTOM);
// paint scroll back data // get key input switch(scrollkeys()){ case VK_ESCAPE: done = TRUE; break; case VK_PRIOR: if ( current > CON_HEIGHT) current-= CON_HEIGHT; else current = 0; break; case VK_NEXT: if ( current < maxlines - 2*CON_HEIGHT + 2) current += CON_HEIGHT; else current = maxlines - CON_HEIGHT + 1; break; case VK_DOWN: if (current <= maxlines - CON_HEIGHT) current++; break; case VK_UP: if ( current > 0) current--; break; case VK_TAB: iDisplay = (iDisplay+1)%4; maxlines = setmaxlines(iDisplay, iScrollLast + 1, strippedlines, CON_COLS); if(current > maxlines) current = maxlines - 1; if(current < 0) current = 0; break; case VK_END: current = maxlines - CON_HEIGHT + 1; if(current < 0) current = 0; break; case VK_HOME: current = 0; break; case SC_MOUSE: Mouse.scrollMouse(); break; } }
// Clean up restoreScreen(chiBuffer); delete[] szStatusLine; delete[] chiBuffer; delete[] stripped;}