ReactOS  0.4.11-dev-946-g431643b
tscroll.cpp
Go to the documentation of this file.
1 //Telnet Win32 : an ANSI telnet client.
3 //Copyright (C) 1998-2000 Paul Brannan
4 //Copyright (C) 1998 I.Ioannou
5 //Copyright (C) 1997 Brad Johnson
6 //
7 //This program is free software; you can redistribute it and/or
8 //modify it under the terms of the GNU General Public License
9 //as published by the Free Software Foundation; either version 2
10 //of the License, or (at your option) any later version.
11 //
12 //This program is distributed in the hope that it will be useful,
13 //but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 //GNU General Public License for more details.
16 //
17 //You should have received a copy of the GNU General Public License
18 //along with this program; if not, write to the Free Software
19 //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 //I.Ioannou
22 //roryt@hol.gr
23 //
25 
27 //
28 // Module: tscroll.cpp
29 //
30 // Contents: Telnet Handler
31 //
32 // Product: telnet
33 //
34 // Revisions: Dec. 5, 1998 Paul Brannan <pbranna@clemson.edu>
35 // June 15, 1998 Paul Brannan
36 //
37 // This is code originally from tnclass.cpp and ansiprsr.cpp
38 //
40 
41 #include "precomp.h"
42 
43 enum {
44  HEX,
48 };
49 
50 int DummyStripBuffer(char *start, char *end, int width) {return 0;}
51 
53  iScrollSize = size;
54  pcScrollData = new char[iScrollSize];
55  iScrollEnd = 0;
56  iPastEnd = 0;
58 
59  if(stricmp(ini.get_scroll_mode(), "hex") == 0) iDisplay = HEX;
60  else if(stricmp(ini.get_scroll_mode(), "dump") == 0) iDisplay = DUMP;
61  else if(stricmp(ini.get_scroll_mode(), "dumpb") == 0) iDisplay = DUMPB;
62  else if(stricmp(ini.get_scroll_mode(), "text") == 0) iDisplay = TEXTB;
63  else iDisplay = DUMP;
64 
66 }
67 
69  delete[] pcScrollData;
70 }
71 
73  strip = s;
74 }
75 
76 // Fixed update of circular buffer (Paul Brannan 12/4/98)
77 // Note: iScrollEnd is one character beyond the end
78 void TScroller::update(const char *pszHead, const char *pszTail) {
79  if ((iScrollEnd)+(pszTail-pszHead) < iScrollSize) {
80  memcpy(&pcScrollData[iScrollEnd], pszHead, pszTail-pszHead);
81  } else if (pszTail-pszHead > iScrollSize) {
83  iScrollEnd = 0;
84  } else {
85  memcpy(&pcScrollData[iScrollEnd], pszHead, iScrollSize-iScrollEnd);
86  memcpy(&pcScrollData[0], pszHead + (iScrollSize-iScrollEnd),
87  pszTail-pszHead-(iScrollSize-iScrollEnd));
88  }
89 
90  // This could probably be optimized better, but it's probably not worth it
91  int temp = iScrollEnd;
92  iScrollEnd = ((iScrollEnd)+(pszTail-pszHead))%iScrollSize;
93  if(iScrollEnd < temp) iPastEnd = 1;
94 }
95 
96 // Perhaps this should be moved to Tconsole.cpp? (Paul Brannan 6/12/98)
98  HANDLE hConsoleOutput, // handle of a console screen buffer
99  CHAR * lpWriteBuffer,
100  WORD wAttrib,
101  SHORT sX,
102  SHORT sY ){
103  // we ought to allocate memory before writing to an address (PB 5/12/98)
104  DWORD cWritten;
105  const LPDWORD lpcWritten = &cWritten;
106 
107  DWORD cWriteCells = strlen(lpWriteBuffer);
108  COORD coordWrite = {sX,sY};
109  LPWORD lpwAttribute = new WORD[cWriteCells];
110  for (unsigned int i = 0; i < cWriteCells; i++)
111  lpwAttribute[i] = wAttrib;
113  hConsoleOutput, // handle of a console screen buffer
114  lpwAttribute, // address of buffer to write attributes from
115  cWriteCells, // number of character cells to write to
116  coordWrite, // coordinates of first cell to write to
117  lpcWritten // address of number of cells written to
118  );
120  hConsoleOutput, // handle of a console screen buffer
121  lpWriteBuffer, // address of buffer to write characters from
122  cWriteCells, // number of character cells to write to
123  coordWrite, // coordinates of first cell to write to
124  lpcWritten // address of number of cells written to
125  );
126  delete [] lpwAttribute;
127  return 1;
128 }
129 
130 static void hexify(int x, char *str, int len) {
131  for(int j = len - 1; j >= 0; j--) {
132  str[j] = x % 16;
133  if(str[j] > 9) str[j] += 'A' - 10;
134  else str[j] += '0';
135  x /= 16;
136  }
137 }
138 
139 static int setmaxlines(int iDisplay, int iScrollSize, int strippedlines,
140  int con_width) {
141  switch(iDisplay) {
142  case HEX: return(iScrollSize / 16); break;
143  case DUMP:
144  case DUMPB: return(iScrollSize / con_width); break;
145  case TEXTB: return(strippedlines); break;
146  }
147  return 0;
148 }
149 
150 static void setstatusline(char *szStatusLine, int len, int iDisplay) {
151  memset(szStatusLine, ' ', len);
152  memcpy(&szStatusLine[1], "Scrollback Mode", 15);
153  switch(iDisplay) {
154  case HEX: memcpy(&szStatusLine[len / 2 - 1], "HEX", 3); break;
155  case DUMP: memcpy(&szStatusLine[len / 2 - 2], "DUMP", 4); break;
156  case DUMPB: memcpy(&szStatusLine[len / 2 - 5], "BINARY DUMP", 11); break;
157  case TEXTB: memcpy(&szStatusLine[len / 2 - 2], "TEXT", 4); break;
158  }
159  memcpy(&szStatusLine[len - 6], "READY", 5);
160  szStatusLine[len] = 0;
161 }
162 
164  char p;
165  int r,c;
166 
167  // define colors (Paul Brannan 7/5/98)
168  int normal = (ini.get_scroll_bg() << 4) | ini.get_scroll_fg();
169  // int inverse = (ini.get_scroll_fg() << 4) | ini.get_scroll_bg();
170  int status = (ini.get_status_bg() << 4) | ini.get_status_fg();
171 
172  CHAR_INFO* chiBuffer;
173  chiBuffer = newBuffer();
174  saveScreen(chiBuffer);
175 
178  GetConsoleScreenBufferInfo(hStdout, &ConsoleInfo);
179 
180  // Update iScrollBegin -- necessary in case the buffer isn't full yet
181  long iScrollBegin, iScrollLast;
182  if(iPastEnd == 0) {
183  iScrollBegin = 0;
184  iScrollLast = iScrollEnd - 1;
185  } else {
186  iScrollBegin = iScrollEnd;
187  iScrollLast = iScrollSize - 1;
188  }
189 
190  // Create buffer with ANSI codes stripped
191  // Fixed this to work properly with a circular buffer (PB 12/4/98)
192  char *stripped = new char[iScrollSize];
193  memcpy(stripped, pcScrollData + iScrollBegin, iScrollSize -
194  iScrollBegin);
195  if(iScrollBegin != 0) memcpy(stripped + (iScrollSize - iScrollBegin),
196  pcScrollData, iScrollBegin - 1);
197  int strippedlines = (*strip)(stripped, stripped + iScrollLast,
198  CON_COLS);
199 
200  // Calculate the last line of the scroll buffer (Paul Brannan 12/4/98)
201  int maxlines = setmaxlines(iDisplay, iScrollLast + 1, strippedlines,
202  CON_COLS);
203 
204  // init scroll position
205  int current = maxlines - CON_HEIGHT + 1;
206  if(current < 0) current = 0;
207 
208  // paint border and info
209  // paint last two lines black on white
210  char * szStatusLine;
211  szStatusLine = new char[CON_WIDTH+2];
212  setstatusline(szStatusLine, CON_COLS, iDisplay);
213  WriteConsoleOutputCharAndAttribute(hStdout, szStatusLine, status,
215 
216  // loop while not done
217  BOOL done = FALSE;
218  while (!done){
219  switch (iDisplay){
220  case HEX:
221  memset(szStatusLine, ' ', CON_COLS);
222  szStatusLine[8] = ':';
223  szStatusLine[34] = '-';
224  for (r = 0; r < CON_HEIGHT; r++) {
225  hexify((r + current) * 16, &szStatusLine[2], 6);
226  for (c = 0; c < 16; c++){
227  if (c+(16*(r+current)) >= iScrollLast)
228  p = 0;
229  else
230  p = pcScrollData[(c+16*(r+current) + iScrollBegin) %
231  iScrollSize];
232  hexify((char)p, &szStatusLine[11 + 3*c], 2);
233  if (!iscntrl(p)) {
234  szStatusLine[60 + c] = (char)p;
235  } else {
236  szStatusLine[60 + c] = '.';
237  }
238  }
239  for(int j = 0; j < 16; j++) {
240  }
241  szStatusLine[CON_COLS] = '\0';
242  WriteConsoleOutputCharAndAttribute(hStdout, szStatusLine,
243  normal, CON_LEFT, r+CON_TOP);
244  }
245  break;
246  case DUMP:
247  for (r = 0; r < CON_HEIGHT; r++) {
248  for (c = 0; c <= CON_WIDTH; c++) {
249  if (c+((CON_COLS)*(r+current)) >= iScrollLast) p = ' ';
250  else p = pcScrollData[(c+((CON_COLS)*(r+current))
251  + iScrollBegin) % iScrollSize];
252  if (!iscntrl(p))
253  szStatusLine[c] = p;
254  else
255  szStatusLine[c] = '.';
256  }
257  szStatusLine[c] = '\0';
258  WriteConsoleOutputCharAndAttribute(hStdout, szStatusLine,
259  normal, CON_LEFT, r+CON_TOP);
260  }
261  break;
262  case DUMPB:
263  for (r = 0; r < CON_HEIGHT; r++) {
264  for (c = 0; c <= CON_WIDTH; c++) {
265  if (c+((CON_COLS)*(r+current)) >= iScrollLast) p = ' ';
266  else p = pcScrollData[ (c+((CON_COLS)*(r+current))
267  + iScrollBegin) % iScrollSize];
268  if (p != 0)
269  szStatusLine[c] = p;
270  else
271  szStatusLine[c] = ' ';
272  }
273  szStatusLine[c] = '\0';
274  WriteConsoleOutputCharAndAttribute(hStdout, szStatusLine,
275  normal, CON_LEFT, r+CON_TOP);
276  }
277  break;
278  case TEXTB: {
279  int ch, lines, x;
280  // Find the starting position
281  for(ch = 0, lines = 0, x = 1; ch < iScrollSize &&
282  lines < current; ch++, x++) {
283 
284  if(stripped[ch] == '\n') lines++;
285  if(stripped[ch] == '\r') x = 1;
286  }
287 
288  for (r = 0; r < CON_HEIGHT; r++) {
289  memset(szStatusLine, ' ', CON_COLS);
290  for(c = 0; c <= CON_WIDTH; c++) {
291  done = FALSE;
292  if (ch >= iScrollSize) p = ' ';
293  else p = stripped[ch];
294  switch(p) {
295  case 10: done = TRUE; break;
296  case 13: c = 0; break;
297  default: szStatusLine[c] = p;
298  }
299  ch++;
300  if(done) break;
301  }
302  szStatusLine[CON_COLS] = '\0';
303  WriteConsoleOutputCharAndAttribute(hStdout, szStatusLine,
304  normal, CON_LEFT, r+CON_TOP);
305  }
306  }
307  break;
308  }
309 
310  setstatusline(szStatusLine, CON_COLS, iDisplay);
311  WriteConsoleOutputCharAndAttribute(hStdout, szStatusLine, status,
313 
314  // paint scroll back data
315  // get key input
316  switch(scrollkeys()){
317  case VK_ESCAPE:
318  done = TRUE;
319  break;
320  case VK_PRIOR:
321  if ( current > CON_HEIGHT)
322  current-= CON_HEIGHT;
323  else
324  current = 0;
325  break;
326  case VK_NEXT:
327  if ( current < maxlines - 2*CON_HEIGHT + 2)
328  current += CON_HEIGHT;
329  else
330  current = maxlines - CON_HEIGHT + 1;
331  break;
332  case VK_DOWN:
333  if (current <= maxlines - CON_HEIGHT) current++;
334  break;
335  case VK_UP:
336  if ( current > 0) current--;
337  break;
338  case VK_TAB:
339  iDisplay = (iDisplay+1)%4;
340  maxlines = setmaxlines(iDisplay, iScrollLast + 1, strippedlines,
341  CON_COLS);
342  if(current > maxlines) current = maxlines - 1;
343  if(current < 0) current = 0;
344  break;
345  case VK_END:
346  current = maxlines - CON_HEIGHT + 1;
347  if(current < 0) current = 0;
348  break;
349  case VK_HOME:
350  current = 0;
351  break;
352  case SC_MOUSE:
353  Mouse.scrollMouse();
354  break;
355  }
356  }
357 
358  // Clean up
359  restoreScreen(chiBuffer);
360  delete[] szStatusLine;
361  delete[] chiBuffer;
362  delete[] stripped;
363 }
#define CON_LEFT
Definition: tconsole.h:48
GLint GLint GLsizei width
Definition: gl.h:1546
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
#define TRUE
Definition: types.h:120
int iDisplay
Definition: tscroll.h:14
int get_scroll_bg() const
Definition: tnconfig.h:73
static int setmaxlines(int iDisplay, int iScrollSize, int strippedlines, int con_width)
Definition: tscroll.cpp:139
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int() stripfunc(char *, char *, int)
Definition: tscroll.h:6
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
stripfunc * strip
Definition: tscroll.h:15
char CHAR
Definition: xmlstorage.h:175
void init(stripfunc *s)
Definition: tscroll.cpp:72
TMouse & Mouse
Definition: tscroll.h:16
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:152
#define CON_TOP
Definition: tconsole.h:45
WORD scrollkeys()
Definition: tncon.cpp:320
#define CON_HEIGHT
Definition: tconsole.h:51
#define VK_TAB
Definition: winuser.h:2153
GLuint GLuint end
Definition: gl.h:1545
#define VK_DOWN
Definition: winuser.h:2181
#define VK_PRIOR
Definition: winuser.h:2174
#define VK_ESCAPE
Definition: winuser.h:2168
Definition: tscroll.cpp:44
#define VK_NEXT
Definition: winuser.h:2175
void saveScreen(CHAR_INFO *chiBuffer)
Definition: tconsole.cpp:934
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define VK_HOME
Definition: winuser.h:2177
static void setstatusline(char *szStatusLine, int len, int iDisplay)
Definition: tscroll.cpp:150
#define VK_UP
Definition: winuser.h:2179
short SHORT
Definition: pedump.c:59
#define CON_WIDTH
Definition: tconsole.h:52
const WCHAR * str
#define M(row, col)
unsigned char
Definition: typeof.h:27
int get_scroll_fg() const
Definition: tnconfig.h:74
long iScrollEnd
Definition: tscroll.h:12
Definition: tscroll.cpp:45
BOOL WINAPI GetConsoleScreenBufferInfo(IN HANDLE hConsoleOutput, OUT PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
Definition: console.c:544
_Check_return_ _CRTIMP int __cdecl stricmp(_In_z_ const char *_Str1, _In_z_ const char *_Str2)
TConfig ini
Definition: tnconfig.cpp:45
int iPastEnd
Definition: tscroll.h:13
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizeiptr size
Definition: glext.h:5919
const char * get_scroll_mode() const
Definition: tnconfig.h:89
#define CON_BOTTOM
Definition: tconsole.h:46
CHAR_INFO * newBuffer()
Definition: tconsole.cpp:995
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
char * pcScrollData
Definition: tscroll.h:10
void restoreScreen(CHAR_INFO *chiBuffer)
Definition: tconsole.cpp:964
static BOOL WriteConsoleOutputCharAndAttribute(HANDLE hConsoleOutput, CHAR *lpWriteBuffer, WORD wAttrib, SHORT sX, SHORT sY)
Definition: tscroll.cpp:97
void scrollMouse()
Definition: tmouse.cpp:207
int DummyStripBuffer(char *start, char *end, int width)
Definition: tscroll.cpp:50
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
GLdouble s
Definition: gl.h:2039
Definition: tncon.h:11
#define STD_OUTPUT_HANDLE
Definition: winbase.h:265
static stack_node_t temp
Definition: rpn.c:18
Definition: bl.h:1338
long iScrollSize
Definition: tscroll.h:11
uint16_t * LPWORD
Definition: typedefs.h:54
_Check_return_ _CRTIMP int __cdecl iscntrl(_In_ int _C)
int get_status_fg() const
Definition: tnconfig.h:76
INT x
Definition: msvc.h:62
GLuint start
Definition: gl.h:1545
static CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo
Definition: video.c:47
TScroller(TMouse &M, int size=20000)
Definition: tscroll.cpp:52
static void hexify(int x, char *str, int len)
Definition: tscroll.cpp:130
void ScrollBack()
Definition: tscroll.cpp:163
HANDLE hStdout
Definition: ctm.c:56
void update(const char *pszBegin, const char *pszEnd)
Definition: tscroll.cpp:78
uint32_t * LPDWORD
Definition: typedefs.h:57
#define c
Definition: ke_i.h:80
int get_status_bg() const
Definition: tnconfig.h:75
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleOutputAttribute(IN HANDLE hConsoleOutput, IN CONST WORD *lpAttribute, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfAttrsWritten)
Definition: readwrite.c:1655
GLfloat GLfloat p
Definition: glext.h:8902
#define WriteConsoleOutputCharacter
Definition: wincon.h:777
Definition: tmouse.h:6
#define memset(x, y, z)
Definition: compat.h:39
~TScroller()
Definition: tscroll.cpp:68
#define VK_END
Definition: winuser.h:2176
#define CON_COLS
Definition: tconsole.h:54
struct task_struct * current
Definition: linux.c:32
Definition: ps.c:97