Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentscroll.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: tscroll.cpp 00029 // 00030 // Contents: Telnet Handler 00031 // 00032 // Product: telnet 00033 // 00034 // Revisions: Dec. 5, 1998 Paul Brannan <pbranna@clemson.edu> 00035 // June 15, 1998 Paul Brannan 00036 // 00037 // This is code originally from tnclass.cpp and ansiprsr.cpp 00038 // 00040 00041 #include "precomp.h" 00042 00043 enum { 00044 HEX, 00045 DUMP, 00046 DUMPB, 00047 TEXTB, 00048 }; 00049 00050 int DummyStripBuffer(char *start, char *end, int width) {return 0;} 00051 00052 TScroller::TScroller(TMouse &M, int size) : Mouse(M) { 00053 iScrollSize = size; 00054 pcScrollData = new char[iScrollSize]; 00055 iScrollEnd = 0; 00056 iPastEnd = 0; 00057 memset(pcScrollData, ' ', iScrollSize); 00058 00059 if(stricmp(ini.get_scroll_mode(), "hex") == 0) iDisplay = HEX; 00060 else if(stricmp(ini.get_scroll_mode(), "dump") == 0) iDisplay = DUMP; 00061 else if(stricmp(ini.get_scroll_mode(), "dumpb") == 0) iDisplay = DUMPB; 00062 else if(stricmp(ini.get_scroll_mode(), "text") == 0) iDisplay = TEXTB; 00063 else iDisplay = DUMP; 00064 00065 strip = &DummyStripBuffer; 00066 } 00067 00068 TScroller::~TScroller() { 00069 delete[] pcScrollData; 00070 } 00071 00072 void TScroller::init(stripfunc *s) { 00073 strip = s; 00074 } 00075 00076 // Fixed update of circular buffer (Paul Brannan 12/4/98) 00077 // Note: iScrollEnd is one character beyond the end 00078 void TScroller::update(const char *pszHead, const char *pszTail) { 00079 if ((iScrollEnd)+(pszTail-pszHead) < iScrollSize) { 00080 memcpy(&pcScrollData[iScrollEnd], pszHead, pszTail-pszHead); 00081 } else if (pszTail-pszHead > iScrollSize) { 00082 memcpy(pcScrollData, pszTail-iScrollSize, iScrollSize); 00083 iScrollEnd = 0; 00084 } else { 00085 memcpy(&pcScrollData[iScrollEnd], pszHead, iScrollSize-iScrollEnd); 00086 memcpy(&pcScrollData[0], pszHead + (iScrollSize-iScrollEnd), 00087 pszTail-pszHead-(iScrollSize-iScrollEnd)); 00088 } 00089 00090 // This could probably be optimized better, but it's probably not worth it 00091 int temp = iScrollEnd; 00092 iScrollEnd = ((iScrollEnd)+(pszTail-pszHead))%iScrollSize; 00093 if(iScrollEnd < temp) iPastEnd = 1; 00094 } 00095 00096 // Perhaps this should be moved to Tconsole.cpp? (Paul Brannan 6/12/98) 00097 static BOOL WriteConsoleOutputCharAndAttribute( 00098 HANDLE hConsoleOutput, // handle of a console screen buffer 00099 CHAR * lpWriteBuffer, 00100 WORD wAttrib, 00101 SHORT sX, 00102 SHORT sY ){ 00103 // we ought to allocate memory before writing to an address (PB 5/12/98) 00104 DWORD cWritten; 00105 const LPDWORD lpcWritten = &cWritten; 00106 00107 DWORD cWriteCells = strlen(lpWriteBuffer); 00108 COORD coordWrite = {sX,sY}; 00109 LPWORD lpwAttribute = new WORD[cWriteCells]; 00110 for (unsigned int i = 0; i < cWriteCells; i++) 00111 lpwAttribute[i] = wAttrib; 00112 WriteConsoleOutputAttribute( 00113 hConsoleOutput, // handle of a console screen buffer 00114 lpwAttribute, // address of buffer to write attributes from 00115 cWriteCells, // number of character cells to write to 00116 coordWrite, // coordinates of first cell to write to 00117 lpcWritten // address of number of cells written to 00118 ); 00119 WriteConsoleOutputCharacter( 00120 hConsoleOutput, // handle of a console screen buffer 00121 lpWriteBuffer, // address of buffer to write characters from 00122 cWriteCells, // number of character cells to write to 00123 coordWrite, // coordinates of first cell to write to 00124 lpcWritten // address of number of cells written to 00125 ); 00126 delete [] lpwAttribute; 00127 return 1; 00128 } 00129 00130 static void hexify(int x, char *str, int len) { 00131 for(int j = len - 1; j >= 0; j--) { 00132 str[j] = x % 16; 00133 if(str[j] > 9) str[j] += 'A' - 10; 00134 else str[j] += '0'; 00135 x /= 16; 00136 } 00137 } 00138 00139 static int setmaxlines(int iDisplay, int iScrollSize, int strippedlines, 00140 int con_width) { 00141 switch(iDisplay) { 00142 case HEX: return(iScrollSize / 16); break; 00143 case DUMP: 00144 case DUMPB: return(iScrollSize / con_width); break; 00145 case TEXTB: return(strippedlines); break; 00146 } 00147 return 0; 00148 } 00149 00150 static void setstatusline(char *szStatusLine, int len, int iDisplay) { 00151 memset(szStatusLine, ' ', len); 00152 memcpy(&szStatusLine[1], "Scrollback Mode", 15); 00153 switch(iDisplay) { 00154 case HEX: memcpy(&szStatusLine[len / 2 - 1], "HEX", 3); break; 00155 case DUMP: memcpy(&szStatusLine[len / 2 - 2], "DUMP", 4); break; 00156 case DUMPB: memcpy(&szStatusLine[len / 2 - 5], "BINARY DUMP", 11); break; 00157 case TEXTB: memcpy(&szStatusLine[len / 2 - 2], "TEXT", 4); break; 00158 } 00159 memcpy(&szStatusLine[len - 6], "READY", 5); 00160 szStatusLine[len] = 0; 00161 } 00162 00163 void TScroller::ScrollBack(){ 00164 char p; 00165 int r,c; 00166 00167 // define colors (Paul Brannan 7/5/98) 00168 int normal = (ini.get_scroll_bg() << 4) | ini.get_scroll_fg(); 00169 // int inverse = (ini.get_scroll_fg() << 4) | ini.get_scroll_bg(); 00170 int status = (ini.get_status_bg() << 4) | ini.get_status_fg(); 00171 00172 CHAR_INFO* chiBuffer; 00173 chiBuffer = newBuffer(); 00174 saveScreen(chiBuffer); 00175 00176 HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 00177 CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo; 00178 GetConsoleScreenBufferInfo(hStdout, &ConsoleInfo); 00179 00180 // Update iScrollBegin -- necessary in case the buffer isn't full yet 00181 long iScrollBegin, iScrollLast; 00182 if(iPastEnd == 0) { 00183 iScrollBegin = 0; 00184 iScrollLast = iScrollEnd - 1; 00185 } else { 00186 iScrollBegin = iScrollEnd; 00187 iScrollLast = iScrollSize - 1; 00188 } 00189 00190 // Create buffer with ANSI codes stripped 00191 // Fixed this to work properly with a circular buffer (PB 12/4/98) 00192 char *stripped = new char[iScrollSize]; 00193 memcpy(stripped, pcScrollData + iScrollBegin, iScrollSize - 00194 iScrollBegin); 00195 if(iScrollBegin != 0) memcpy(stripped + (iScrollSize - iScrollBegin), 00196 pcScrollData, iScrollBegin - 1); 00197 int strippedlines = (*strip)(stripped, stripped + iScrollLast, 00198 CON_COLS); 00199 00200 // Calculate the last line of the scroll buffer (Paul Brannan 12/4/98) 00201 int maxlines = setmaxlines(iDisplay, iScrollLast + 1, strippedlines, 00202 CON_COLS); 00203 00204 // init scroll position 00205 int current = maxlines - CON_HEIGHT + 1; 00206 if(current < 0) current = 0; 00207 00208 // paint border and info 00209 // paint last two lines black on white 00210 char * szStatusLine; 00211 szStatusLine = new char[CON_WIDTH+2]; 00212 setstatusline(szStatusLine, CON_COLS, iDisplay); 00213 WriteConsoleOutputCharAndAttribute(hStdout, szStatusLine, status, 00214 CON_LEFT, CON_BOTTOM); 00215 00216 // loop while not done 00217 BOOL done = FALSE; 00218 while (!done){ 00219 switch (iDisplay){ 00220 case HEX: 00221 memset(szStatusLine, ' ', CON_COLS); 00222 szStatusLine[8] = ':'; 00223 szStatusLine[34] = '-'; 00224 for (r = 0; r < CON_HEIGHT; r++) { 00225 hexify((r + current) * 16, &szStatusLine[2], 6); 00226 for (c = 0; c < 16; c++){ 00227 if (c+(16*(r+current)) >= iScrollLast) 00228 p = 0; 00229 else 00230 p = pcScrollData[(c+16*(r+current) + iScrollBegin) % 00231 iScrollSize]; 00232 hexify((char)p, &szStatusLine[11 + 3*c], 2); 00233 if (!iscntrl(p)) { 00234 szStatusLine[60 + c] = (char)p; 00235 } else { 00236 szStatusLine[60 + c] = '.'; 00237 } 00238 } 00239 for(int j = 0; j < 16; j++) { 00240 } 00241 szStatusLine[CON_COLS] = '\0'; 00242 WriteConsoleOutputCharAndAttribute(hStdout, szStatusLine, 00243 normal, CON_LEFT, r+CON_TOP); 00244 } 00245 break; 00246 case DUMP: 00247 for (r = 0; r < CON_HEIGHT; r++) { 00248 for (c = 0; c <= CON_WIDTH; c++) { 00249 if (c+((CON_COLS)*(r+current)) >= iScrollLast) p = ' '; 00250 else p = pcScrollData[(c+((CON_COLS)*(r+current)) 00251 + iScrollBegin) % iScrollSize]; 00252 if (!iscntrl(p)) 00253 szStatusLine[c] = p; 00254 else 00255 szStatusLine[c] = '.'; 00256 } 00257 szStatusLine[c] = '\0'; 00258 WriteConsoleOutputCharAndAttribute(hStdout, szStatusLine, 00259 normal, CON_LEFT, r+CON_TOP); 00260 } 00261 break; 00262 case DUMPB: 00263 for (r = 0; r < CON_HEIGHT; r++) { 00264 for (c = 0; c <= CON_WIDTH; c++) { 00265 if (c+((CON_COLS)*(r+current)) >= iScrollLast) p = ' '; 00266 else p = pcScrollData[ (c+((CON_COLS)*(r+current)) 00267 + iScrollBegin) % iScrollSize]; 00268 if (p != 0) 00269 szStatusLine[c] = p; 00270 else 00271 szStatusLine[c] = ' '; 00272 } 00273 szStatusLine[c] = '\0'; 00274 WriteConsoleOutputCharAndAttribute(hStdout, szStatusLine, 00275 normal, CON_LEFT, r+CON_TOP); 00276 } 00277 break; 00278 case TEXTB: { 00279 int ch, lines, x; 00280 // Find the starting position 00281 for(ch = 0, lines = 0, x = 1; ch < iScrollSize && 00282 lines < current; ch++, x++) { 00283 00284 if(stripped[ch] == '\n') lines++; 00285 if(stripped[ch] == '\r') x = 1; 00286 } 00287 00288 for (r = 0; r < CON_HEIGHT; r++) { 00289 memset(szStatusLine, ' ', CON_COLS); 00290 for(c = 0; c <= CON_WIDTH; c++) { 00291 done = FALSE; 00292 if (ch >= iScrollSize) p = ' '; 00293 else p = stripped[ch]; 00294 switch(p) { 00295 case 10: done = TRUE; break; 00296 case 13: c = 0; break; 00297 default: szStatusLine[c] = p; 00298 } 00299 ch++; 00300 if(done) break; 00301 } 00302 szStatusLine[CON_COLS] = '\0'; 00303 WriteConsoleOutputCharAndAttribute(hStdout, szStatusLine, 00304 normal, CON_LEFT, r+CON_TOP); 00305 } 00306 } 00307 break; 00308 } 00309 00310 setstatusline(szStatusLine, CON_COLS, iDisplay); 00311 WriteConsoleOutputCharAndAttribute(hStdout, szStatusLine, status, 00312 CON_LEFT, CON_BOTTOM); 00313 00314 // paint scroll back data 00315 // get key input 00316 switch(scrollkeys()){ 00317 case VK_ESCAPE: 00318 done = TRUE; 00319 break; 00320 case VK_PRIOR: 00321 if ( current > CON_HEIGHT) 00322 current-= CON_HEIGHT; 00323 else 00324 current = 0; 00325 break; 00326 case VK_NEXT: 00327 if ( current < maxlines - 2*CON_HEIGHT + 2) 00328 current += CON_HEIGHT; 00329 else 00330 current = maxlines - CON_HEIGHT + 1; 00331 break; 00332 case VK_DOWN: 00333 if (current <= maxlines - CON_HEIGHT) current++; 00334 break; 00335 case VK_UP: 00336 if ( current > 0) current--; 00337 break; 00338 case VK_TAB: 00339 iDisplay = (iDisplay+1)%4; 00340 maxlines = setmaxlines(iDisplay, iScrollLast + 1, strippedlines, 00341 CON_COLS); 00342 if(current > maxlines) current = maxlines - 1; 00343 if(current < 0) current = 0; 00344 break; 00345 case VK_END: 00346 current = maxlines - CON_HEIGHT + 1; 00347 if(current < 0) current = 0; 00348 break; 00349 case VK_HOME: 00350 current = 0; 00351 break; 00352 case SC_MOUSE: 00353 Mouse.scrollMouse(); 00354 break; 00355 } 00356 } 00357 00358 // Clean up 00359 restoreScreen(chiBuffer); 00360 delete[] szStatusLine; 00361 delete[] chiBuffer; 00362 delete[] stripped; 00363 } Generated on Sun May 27 2012 04:17:18 for ReactOS by
1.7.6.1
|