tscroll.cpp
上传用户:haiweijt
上传日期:2018-02-23
资源大小:8195k
文件大小:11k
- ///////////////////////////////////////////////////////////////////////////////
- //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 <windows.h>
- #include <string.h>
- #include <ctype.h>
- #include "tscroll.h"
- #include "tncon.h"
- #include "tconsole.h"
- #include "tnconfig.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 end
- void 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] = ' ';
- 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] = ' ';
- 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] = ' ';
- 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++) {
- int 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] = ' ';
- 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;
- }