tconsole.cpp
上传用户:haiweijt
上传日期:2018-02-23
资源大小:8195k
文件大小:30k
- ///////////////////////////////////////////////////////////////////////////////
- //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: tconsole.cpp
- //
- // Contents: screen functions
- //
- // Product: telnet
- //
- //
- // Revisions: Mar. 29, 2000 pbranna@clemson (Paul Brannan)
- // June 15, 1998 pbranna@clemson.edu
- // May 16, 1998 pbranna@clemson.edu
- // 05. Sep.1997 roryt@hol.gr (I.Ioannou)
- // 11.May,1997 roryt@hol.gr
- // 06.April,1997 roryt@hol.gr
- // 30.M剅z.1997 Titus_Boxberg@public.uni-hamburg.de
- // 5.Dec.1996 jbj@nounname.com
- // Version 2.0
- // 02.Apr.1995 igor.milavec@uni-lj.si
- // Original code
- //
- ///////////////////////////////////////////////////////////////////////////////
- #include <windows.h>
- #include "tconsole.h"
- // argsused doesn't work on MSVC++
- #ifdef __BORLANDC__
- #pragma argsused
- #endif
- TConsole::TConsole(HANDLE h) {
- hConsole = h;
- GetConsoleScreenBufferInfo(hConsole, &ConsoleInfo);
- // Start with correct colors
- int fg = ini.get_normal_fg();
- int bg = ini.get_normal_bg();
- if(fg == -1)
- fg = defaultfg = origfg = ConsoleInfo.wAttributes & 0xF;
- else
- defaultfg = origfg = fg;
- if(bg == -1)
- bg = defaultbg = origbg = (ConsoleInfo.wAttributes >> 4) & 0xF;
- else
- defaultbg = origbg = bg;
- wAttributes = fg | (bg << 4);
- reverse = blink = underline = false;
- SetConsoleTextAttribute(hConsole, wAttributes);
- insert_mode = 0;
-
- // Set the screen size
- SetWindowSize(ini.get_term_width(), ini.get_term_height());
- iScrollStart = -1;
- iScrollEnd = -1;
- }
- TConsole::~TConsole() {
- wAttributes = origfg | (origbg << 4);
- SetCursorPosition(0, CON_HEIGHT);
- SetConsoleTextAttribute(hConsole, wAttributes);
- WriteCtrlChar('x0a');
- }
- // Paul Brannan 8/2/98
- void TConsole::SetWindowSize(int width, int height) {
- SMALL_RECT sr = {
- CON_LEFT,
- CON_TOP,
- (width == -1) ? CON_RIGHT : CON_LEFT + width - 1,
- (height == -1) ? CON_BOTTOM : CON_TOP + height - 1
- };
- ConsoleInfo.dwSize.X = width;
- if(ConsoleInfo.dwSize.Y < height) ConsoleInfo.dwSize.Y = height;
- SetConsoleScreenBufferSize(hConsole, ConsoleInfo.dwSize);
- SetConsoleWindowInfo(hConsole, TRUE, &sr);
- SetConsoleScreenBufferSize(hConsole, ConsoleInfo.dwSize);
- sync();
- }
- // Paul Brannan 5/15/98
- void TConsole::sync() {
- GetConsoleScreenBufferInfo(hConsole, &ConsoleInfo);
- }
- void TConsole::HighVideo() {
- wAttributes = wAttributes | (unsigned char) 8;
- }
- void TConsole::LowVideo() {
- wAttributes = wAttributes & (unsigned char) (0xff-8);
- }
- void TConsole::Normal() {
- // I.Ioannou 11 May 1997
- // Color 7 is correct on some systems (for example Linux)
- // but not with others (for example SCO)
- // we must preserve the colors :
- // 06/04/98 thanks to Paul a .ini parameter from now on
-
- BlinkOff();
- UnderlineOff();
- if(ini.get_preserve_colors()) {
- ReverseOff();
- LowVideo();
- } else {
- fg = defaultfg;
- bg = defaultbg;
- wAttributes = (unsigned char)fg | (bg << 4);
- reverse = false;
- }
- }
- void TConsole::SetForeground(unsigned char wAttrib) {
- if(reverse) bg = wAttrib; else fg = wAttrib;
- wAttributes = (wAttributes & (unsigned char)0x88) |
- (unsigned char)fg | (bg << 4);
- }
- void TConsole::SetBackground(unsigned char wAttrib) {
- if(reverse) fg = wAttrib; else bg = wAttrib;
- wAttributes = (wAttributes & (unsigned char)0x88) |
- (unsigned char)fg | (bg << 4);
- }
- // As far as I can tell, there's no such thing as blink in Windows Console.
- // I tried using some inline asm to turn off high-intensity backgrounds,
- // but I got a BSOD. Perhaps there is an undocumented function?
- // (Paul Brannan 6/27/98)
- void TConsole::BlinkOn() {
- blink = 1;
- if(underline) {
- UlBlinkOn();
- } else {
- if(ini.get_blink_bg() != -1) {
- wAttributes &= 0x8f; // turn off bg
- wAttributes |= ini.get_blink_bg() << 4;
- }
- if(ini.get_blink_fg() != -1) {
- wAttributes &= 0xf8; // turn off fg
- wAttributes |= ini.get_blink_fg();
- }
- if(ini.get_blink_bg() == -1 && ini.get_blink_fg() == -1)
- wAttributes |= 0x80;
- }
- }
- // Added by I.Ioannou 06 April, 1997
- void TConsole::BlinkOff() {
- blink = 0;
- if(underline) {
- UlBlinkOff();
- } else {
- if(ini.get_blink_bg() != -1) {
- wAttributes &= 0x8f; // turn off bg
- wAttributes |= defaultbg << 4;
- }
- if(ini.get_blink_fg() != -1) {
- wAttributes &= 0xf8; // turn off fg
- wAttributes |= defaultfg;
- }
- if(ini.get_blink_bg() == -1 && ini.get_blink_fg() == -1)
- wAttributes &= 0x7f;
- }
- }
- // Paul Brannan 6/27/98
- void TConsole::UnderlineOn() {
- underline = 1;
- if(blink) {
- UlBlinkOn();
- } else {
- if(ini.get_underline_bg() != -1) {
- wAttributes &= 0x8f; // turn off bg
- wAttributes |= ini.get_underline_bg() << 4;
- }
- if(ini.get_underline_fg() != -1) {
- wAttributes &= 0xf8; // turn off fg
- wAttributes |= ini.get_underline_fg();
- }
- if(ini.get_underline_bg() == -1 && ini.get_underline_fg() == -1)
- wAttributes |= 0x80;
- }
- }
- // Paul Brannan 6/27/98
- void TConsole::UnderlineOff() {
- underline = 0;
- if(blink) {
- UlBlinkOff();
- } else {
- if(ini.get_blink_bg() != -1) {
- wAttributes &= 0x8f; // turn off bg
- wAttributes |= defaultbg << 4;
- }
- if(ini.get_blink_fg() != -1) {
- wAttributes &= 0xf8; // turn off fg
- wAttributes |= defaultfg;
- }
- if(ini.get_blink_bg() == -1 && ini.get_blink_fg() == -1)
- wAttributes &= 0x7f;
- }
- }
- // Paul Brannan 6/27/98
- void TConsole::UlBlinkOn() {
- if(ini.get_ulblink_bg() != -1) {
- wAttributes &= 0x8f; // turn off bg
- wAttributes |= ini.get_ulblink_bg() << 4;
- }
- if(ini.get_ulblink_fg() != -1) {
- wAttributes &= 0xf8; // turn off fg
- wAttributes |= ini.get_ulblink_fg();
- }
- if(ini.get_ulblink_bg() == -1 && ini.get_ulblink_fg() == -1)
- wAttributes |= 0x80;
- }
- // Paul Brannan 6/27/98
- void TConsole::UlBlinkOff() {
- if(blink) {
- BlinkOn();
- } else if(underline) {
- UnderlineOn();
- } else {
- Normal();
- }
- }
- // Paul Brannan 6/26/98
- void TConsole::Lightbg() {
- WORD *pAttributes = new WORD[CON_COLS];
- DWORD Result;
- // Paul Brannan 8/5/98
- // Correction: processing more than one line at a time causes a segfault
- // if the screen width != 80
- for(int i = CON_TOP; i <= CON_BOTTOM; i++) {
- COORD Coord = {CON_LEFT, i};
- ReadConsoleOutputAttribute(hConsole, pAttributes, (DWORD)(CON_COLS),
- Coord, &Result);
-
- for(DWORD j = 0; j < Result; j++) pAttributes[j] |= 0x80;
- WriteConsoleOutputAttribute(hConsole, pAttributes, Result, Coord,
- &Result);
- }
- delete[] pAttributes; // clean up
- wAttributes |= (unsigned char)0x80;
- bg |= 8;
- }
- // Paul Brannan 6/26/98
- void TConsole::Darkbg() {
- WORD *pAttributes = new WORD[CON_COLS];
- DWORD Result;
- // Paul Brannan 8/5/98
- // Correction: processing more than one line at a time causes a segfault
- // if the screen width != 80
- for(int i = CON_TOP; i <= CON_BOTTOM; i++) {
- COORD Coord = {CON_LEFT, i};
- ReadConsoleOutputAttribute(hConsole, pAttributes, (DWORD)(CON_COLS),
- Coord, &Result);
-
- for(DWORD j = 0; j < Result; j++) pAttributes[j] &= 0x7f;
- WriteConsoleOutputAttribute(hConsole, pAttributes, Result, Coord,
- &Result);
- }
- delete[] pAttributes; // clean up
- wAttributes &= (unsigned char)0x7f;
- bg &= 7;
- }
- // Added by I.Ioannou 11.May,1997
- void TConsole::ReverseOn() {
- if (!reverse) {
- reverse = true;
- // atl : forground attributes without the intensity
- // ath : backgound attributes without the blink
- // bl : the blink state
- // ints : the intensity
- unsigned char atl = wAttributes & (unsigned char) 0x07;
- unsigned char ath = wAttributes & (unsigned char) 0x70;
- unsigned char bl = wAttributes & (unsigned char) 0x80;
- unsigned char ints = wAttributes & (unsigned char) 0x08;
- wAttributes = bl | (atl << 4) | ints | (ath >> 4);
- }
- }
- // Added by I.Ioannou 11.May,1997
- void TConsole::ReverseOff() {
- if (reverse) {
- reverse = false;
- wAttributes = fg | (bg << 4);
- }
- }
- unsigned long TConsole::WriteText(const char *pszString, unsigned long cbString) {
- DWORD Result;
- if(insert_mode) {
- InsertCharacter(cbString);
- }
- WriteConsoleOutputCharacter(hConsole, (char *)pszString, cbString,
- ConsoleInfo.dwCursorPosition, &Result);
- FillConsoleOutputAttribute(hConsole, wAttributes, cbString,
- ConsoleInfo.dwCursorPosition, &Result);
- return Result;
- }
- // Formerly ConWriteString (Paul Brannan 6/28/98)
- unsigned long TConsole::WriteStringFast(const char* pszString, unsigned long cbString) {
- DWORD Result;
- SetConsoleTextAttribute(hConsole, wAttributes);
- //check to see if the line is longer than the display
- if (!getLineWrap() && ((unsigned)CON_CUR_X + cbString) >= (unsigned)CON_COLS) {
- // Take care of the last line last colum exception...
- // The display scrolls up if you use the normal char out
- // function even if you only write to the last place
- // on the line. :-(
- if ((unsigned)CON_CUR_Y >= (unsigned)CON_HEIGHT) {
- unsigned long iFakeResult = cbString;
- cbString = CON_COLS - CON_CUR_X - 1;
- // FIX ME !!! This will avoid the exception when cbString
- // is <= 0 but still doesn't work :-(
- if (cbString > 0)
- WriteConsole(hConsole, pszString, cbString, &Result, 0);
- COORD dwBufferCoord;
- dwBufferCoord.X = 0;
- dwBufferCoord.Y = 0;
- CHAR_INFO ciBuffer;
- ciBuffer.Char.AsciiChar = *(pszString+cbString);
- ciBuffer.Attributes = wAttributes;
- SMALL_RECT srWriteRegion;
- srWriteRegion.Top = (SHORT) CON_BOTTOM;
- srWriteRegion.Bottom = (SHORT) CON_BOTTOM;
- srWriteRegion.Left = (SHORT) CON_RIGHT;
- srWriteRegion.Right = (SHORT) CON_RIGHT;
- COORD bufSize = {1,1};
- WriteConsoleOutput(hConsole, &ciBuffer, bufSize,
- dwBufferCoord, &srWriteRegion);
- // We need to update the ConsoleInfo struct now (Paul Brannan 5/9/98)
- ConsoleInfo.dwCursorPosition.X = CON_RIGHT;
- return iFakeResult; // Skip the chars that did not fit
- }
- // just write the line up to the end
- else {
- int iFakeResult = cbString;
- cbString = CON_COLS - CON_CUR_X;
- if(cbString > 0) {
- WriteConsole(hConsole, pszString, cbString, &Result, 0);
- // We need to update the ConsoleInfo struct now (Paul Brannan 5/9/98)
- ConsoleInfo.dwCursorPosition.X += (unsigned short)Result;
- }
- return iFakeResult; // Skip the chars that did not fit
- }
- } else {
- // If custom scrolling is enabled we must take care of it
- if(iScrollStart != -1 || iScrollEnd != -1) {
- return WriteString(pszString, cbString);
- }
- // Apparently VT100 terminals have an invisible "81st" column that
- // can hold a cursor until another character is printed. I'm not sure
- // exactly how to handle this, but here's a hack (Paul Brannan 5/28/98)
- if(ini.get_vt100_mode() && cbString + (unsigned)CON_CUR_X == (unsigned)CON_COLS) {
- cbString--;
- if(cbString >= 0) WriteConsole(hConsole, pszString, cbString, &Result, 0);
- COORD dwBufferCoord;
- dwBufferCoord.X = 0;
- dwBufferCoord.Y = 0;
- CHAR_INFO ciBuffer;
- ciBuffer.Char.AsciiChar = *(pszString+cbString);
- ciBuffer.Attributes = wAttributes;
- SMALL_RECT srWriteRegion;
- srWriteRegion.Top = (SHORT) ConsoleInfo.dwCursorPosition.Y;
- srWriteRegion.Bottom = (SHORT) ConsoleInfo.dwCursorPosition.Y;
- srWriteRegion.Left = (SHORT) CON_RIGHT;
- srWriteRegion.Right = (SHORT) CON_RIGHT;
- COORD bufSize = {1,1};
- WriteConsoleOutput(hConsole, &ciBuffer, bufSize,
- dwBufferCoord, &srWriteRegion);
- // Update the ConsoleInfo struct
- ConsoleInfo.dwCursorPosition.X = CON_RIGHT + 1;
- return Result + 1;
- }
- // normal line will wrap normally or not to the end of buffer
- WriteConsole(hConsole, pszString, cbString, &Result, 0);
- // We need to update the ConsoleInfo struct now (Paul Brannan 5/9/98)
- // FIX ME!!! This is susceptible to the same problem as above.
- // (e.g. we write out 160 characters)
- ConsoleInfo.dwCursorPosition.X += (unsigned short)Result;
- while(CON_CUR_X > CON_WIDTH) {
- ConsoleInfo.dwCursorPosition.X -= ConsoleInfo.dwSize.X;
- if((unsigned)CON_CUR_Y < (unsigned)CON_HEIGHT) {
- ConsoleInfo.dwCursorPosition.Y++;
- } else {
- // If we aren't at the bottom of the window, then we need to
- // scroll down (Paul Brannan 4/14/2000)
- if(ConsoleInfo.srWindow.Bottom < ConsoleInfo.dwSize.Y - 1) {
- ConsoleInfo.srWindow.Top++;
- ConsoleInfo.srWindow.Bottom++;
- ConsoleInfo.dwCursorPosition.Y++;
- SetConsoleWindowInfo(hConsole, TRUE, &ConsoleInfo.srWindow);
- }
- }
- }
- }
- return Result;
- }
- unsigned long TConsole::WriteString(const char* pszString, unsigned long cbString) {
- DWORD Result = 0;
-
- SetConsoleTextAttribute(hConsole, wAttributes);
- //check to see if the line is longer than the display
- if (!getLineWrap()){
- unsigned long iFakeResult = cbString;
- if((CON_CUR_X + cbString) >= (unsigned int)CON_COLS)
- cbString = CON_COLS - CON_CUR_X;
- if(cbString > 0)
- Result = WriteText(pszString, cbString);
- // We need to update the ConsoleInfo struct now (Paul Brannan 5/9/98)
- ConsoleInfo.dwCursorPosition.X += (unsigned short)Result;
- SetConsoleCursorPosition(hConsole, ConsoleInfo.dwCursorPosition);
- return iFakeResult; // Skip the chars that did not fit
- } else {
- // Write up to the end of the line
- unsigned long temp = cbString;
- if((CON_CUR_X + temp) > (unsigned int)CON_COLS) {
- temp = CON_COLS - CON_CUR_X;
- } else {
- Result = WriteText(pszString, temp);
- ConsoleInfo.dwCursorPosition.X += (unsigned short)Result;
- SetConsoleCursorPosition(hConsole, ConsoleInfo.dwCursorPosition);
- return Result;
- }
- if(temp > 0) {
- Result = WriteText(pszString, temp);
- ConsoleInfo.dwCursorPosition.X += (unsigned short)Result;
- temp = (unsigned short)Result;
- }
- // keep writing lines until we get to less than 80 chars left
- while((temp + (unsigned int)CON_COLS) < cbString) {
- index(); // LF
- ConsoleInfo.dwCursorPosition.X = 0; // CR
- Result = WriteText(&pszString[temp], CON_COLS);
- temp += (unsigned short)Result;
- }
- // write out the last bit
- if(temp < cbString) {
- index();
- ConsoleInfo.dwCursorPosition.X = 0;
- Result = WriteText(&pszString[temp], cbString - temp);
- temp += (unsigned short)Result;
- }
- // Apparently VT100 terminals have an invisible "81st" column that
- // can hold a cursor until another character is printed. I'm not sure
- // exactly how to handle this, but here's a hack (Paul Brannan 5/28/98)
- if(!ini.get_vt100_mode() && cbString + (unsigned)ConsoleInfo.dwCursorPosition.X
- == (unsigned int)CON_COLS) {
- index();
- ConsoleInfo.dwCursorPosition.X = 0;
- }
- SetConsoleCursorPosition(hConsole, ConsoleInfo.dwCursorPosition);
- return temp;
- }
- return 0;
- }
- // This is for multi-character control strings (Paul Brannan 6/26/98)
- unsigned long TConsole::WriteCtrlString(const char *pszString, unsigned long cbString) {
- unsigned long total = 0;
- while(total < cbString) {
- unsigned long Result = WriteCtrlChar(*(pszString + total));
- if(Result == 0) {
- Result = WriteStringFast(pszString + total, 1);
- if(Result == 0) return total;
- }
- total += Result;
- }
- return total;
- }
- // This is for printing single control characters
- // WriteCtrlString uses this (Paul Brannan 6/26/98)
- unsigned long TConsole::WriteCtrlChar(char c) {
- // The console does not handel the CR/LF chars as we might expect
- // when using color. The attributes are not set correctly, so we
- // must interpret them manualy to preserve the colors on the screen.
-
- unsigned long Result = 0; // just in case (Paul Brannan 6/26/98)
- switch (c) {
- case 'x09': // horizontal tab
- SetCursorPosition((((CON_CUR_X/8)+1)*8), CON_CUR_Y);
- Result = 1;
- break;
-
- case 'x0a': // line feed
- index();
- Result = 1;
- break;
- case 'x0d': // carrage return
- SetCursorPosition(CON_LEFT, CON_CUR_Y); // move to beginning of line
- Result = 1;
- break;
- case 'b': // backspace
- // Added support for backspace so the cursor position can be changed
- // (Paul Brannan 5/25/98)
- MoveCursorPosition(-1, 0);
- Result = 1;
- default : // else just write it like normal
- break;
- }
-
- return Result;
- }
- void TConsole::index() {
- // if on the last line scroll up
- // This must work with scrolling (Paul Brannan 5/13/98)
- if(iScrollEnd != -1 && (signed)CON_CUR_Y >= iScrollEnd) {
- ScrollDown(iScrollStart, iScrollEnd, -1);
- } else if ((iScrollEnd == -1 && (signed)CON_CUR_Y >= (signed)CON_HEIGHT)) {
- DWORD Result;
- WriteConsole(hConsole, "n", 1, &Result, NULL);
-
- // If we aren't at the bottom of the buffer, then we need to
- // scroll down (Paul Brannan 4/14/2000)
- if(iScrollEnd == -1 && ConsoleInfo.srWindow.Bottom < ConsoleInfo.dwSize.Y - 1) {
- ConsoleInfo.srWindow.Top++;
- ConsoleInfo.srWindow.Bottom++;
- ConsoleInfo.dwCursorPosition.Y++;
- // SetConsoleWindowInfo(hConsole, TRUE, &ConsoleInfo.srWindow);
- } else {
- ClearLine();
- }
- } else { // else move cursor down to the next line
- SetCursorPosition(CON_CUR_X, CON_CUR_Y + 1);
- }
- }
- void TConsole::reverse_index() {
- // if on the top line scroll down
- // This must work with scrolling (Paul Brannan 5/13/98)
- // We should be comparing against iScrollStart, not iScrollEnd (PB 12/2/98)
- if (iScrollStart == -1 && (signed)CON_CUR_Y <= 0) {
- ScrollDown(iScrollStart, -1, 1);
- } else if (iScrollStart != -1 && (signed)CON_CUR_Y <= iScrollStart) {
- ScrollDown(iScrollStart, iScrollEnd, 1);
- } else // else move cursor up to the previous line
- SetCursorPosition(CON_CUR_X,CON_CUR_Y - 1);
- }
- void TConsole::ScrollDown( int iStartRow , int iEndRow, int bUp ){
- CHAR_INFO ciChar;
- SMALL_RECT srScrollWindow;
-
- // Correction from I.Ioannou 11 May 1997
- // check the scroll region
- if (iStartRow < iScrollStart) iStartRow = iScrollStart;
-
- // Correction from I.Ioannou 11 May 1997
- // this will make Top the CON_TOP
- if ( iStartRow == -1) iStartRow = 0;
- // Correction from I.Ioannou 18 Aug 97
- if ( iEndRow == -1) {
- if ( iScrollEnd == -1 )
- iEndRow = CON_HEIGHT;
- else
- iEndRow = ((CON_HEIGHT <= iScrollEnd) ? CON_HEIGHT : iScrollEnd);
- }
- //
- if ( iStartRow > CON_HEIGHT) iStartRow = CON_HEIGHT;
- if ( iEndRow > CON_HEIGHT) iEndRow = CON_HEIGHT;
-
- srScrollWindow.Left = (CON_LEFT);
- srScrollWindow.Right = (SHORT) (CON_RIGHT);
- srScrollWindow.Top = (SHORT) (CON_TOP + iStartRow );
- srScrollWindow.Bottom = (SHORT) (CON_TOP + iEndRow); // don't subtract 1 (PB 5/28)
- ciChar.Char.AsciiChar = ' '; // fill with spaces
- ciChar.Attributes = wAttributes; // fill with current attrib
-
- // This should speed things up (Paul Brannan 9/2/98)
- COORD dwDestOrg = {srScrollWindow.Left, srScrollWindow.Top + bUp};
-
- // Note that iEndRow and iStartRow had better not be equal to -1 at this
- // point. There are four cases to consider for out of bounds. Two of
- // these cause the scroll window to be cleared; the others cause the
- // scroll region to be modified. (Paul Brannan 12/3/98)
- if(dwDestOrg.Y > CON_TOP + iEndRow) {
- // We are scrolling past the end of the scroll region, so just
- // clear the window instead (Paul Brannan 12/3/98)
- ClearWindow(CON_TOP + iStartRow, CON_TOP + iEndRow);
- return;
- } else if(dwDestOrg.Y + (iEndRow-iStartRow+1) < CON_TOP + iStartRow) {
- // We are scrolling past the end of the scroll region, so just
- // clear the window instead (Paul Brannan 12/3/98)
- ClearWindow(CON_TOP + iStartRow, CON_TOP + iEndRow);
- return;
- } else if(dwDestOrg.Y < CON_TOP + iStartRow) {
- // Modify the scroll region (Paul Brannan 12/3/98)
- dwDestOrg.Y = CON_TOP + iStartRow;
- srScrollWindow.Top -= bUp;
- } else if(dwDestOrg.Y + (iEndRow-iStartRow+1) > CON_TOP + iEndRow) {
- // Modify the scroll region (Paul Brannan 12/3/98)
- srScrollWindow.Bottom -= bUp;
- }
-
- ScrollConsoleScreenBuffer(hConsole, &srScrollWindow,
- 0, dwDestOrg, &ciChar);
- }
- // This allows us to clear the screen with an arbitrary character
- // (Paul Brannan 6/26/98)
- void TConsole::ClearScreen(char c) {
- DWORD dwWritten;
- COORD Coord = {CON_LEFT, CON_TOP};
- FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_COLS)*
- (DWORD)(CON_LINES), Coord, &dwWritten);
- FillConsoleOutputAttribute(hConsole, wAttributes, (DWORD)(CON_COLS)*
- (DWORD)(CON_LINES), Coord, &dwWritten);
- }
- // Same as clear screen, but only affects the scroll region
- void TConsole::ClearWindow(int iStartRow, int iEndRow, char c) {
- DWORD dwWritten;
- COORD Coord = {CON_LEFT, CON_TOP + iStartRow};
- FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_COLS)*
- (DWORD)(iEndRow-iStartRow+1), Coord, &dwWritten);
- FillConsoleOutputAttribute(hConsole, wAttributes, (DWORD)(CON_COLS)*
- (DWORD)(CON_LINES), Coord, &dwWritten);
- }
- // Clear from cursor to end of screen
- void TConsole::ClearEOScreen(char c)
- {
- DWORD dwWritten;
- COORD Coord = {CON_LEFT, CON_TOP + CON_CUR_Y + 1};
- FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_COLS)*
- (DWORD)(CON_HEIGHT - CON_CUR_Y), Coord, &dwWritten);
- FillConsoleOutputAttribute(hConsole, wAttributes, (DWORD)(CON_COLS)*
- (DWORD)(CON_LINES - CON_CUR_Y), Coord, &dwWritten);
- ClearEOLine();
- }
- // Clear from beginning of screen to cursor
- void TConsole::ClearBOScreen(char c)
- {
- DWORD dwWritten;
- COORD Coord = {CON_LEFT, CON_TOP};
- FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_COLS)*
- (DWORD)(CON_CUR_Y), Coord, &dwWritten);
- FillConsoleOutputAttribute(hConsole, wAttributes, (DWORD)(CON_COLS)*
- (DWORD)(CON_CUR_Y), Coord, &dwWritten);
- ClearBOLine();
- }
- void TConsole::ClearLine(char c)
- {
- DWORD dwWritten;
- COORD Coord = {CON_LEFT, CON_TOP + CON_CUR_Y};
- FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_COLS),
- Coord, &dwWritten);
- FillConsoleOutputAttribute(hConsole, wAttributes, (DWORD)(CON_COLS),
- Coord, &dwWritten);
- GetConsoleScreenBufferInfo(hConsole, &ConsoleInfo);
- }
- void TConsole::ClearEOLine(char c)
- {
- DWORD dwWritten;
- COORD Coord = {CON_LEFT + CON_CUR_X, CON_TOP + CON_CUR_Y};
- FillConsoleOutputAttribute(hConsole, wAttributes,
- (DWORD)(CON_RIGHT - CON_CUR_X) +1, Coord, &dwWritten);
- FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_RIGHT - CON_CUR_X) +1,
- Coord, &dwWritten);
- GetConsoleScreenBufferInfo(hConsole, &ConsoleInfo);
- }
- void TConsole::ClearBOLine(char c)
- {
- DWORD dwWritten;
- COORD Coord = {CON_LEFT, CON_TOP + CON_CUR_Y};
- FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_CUR_X) + 1, Coord,
- &dwWritten);
- FillConsoleOutputAttribute(hConsole, wAttributes, (DWORD)(CON_CUR_X) + 1,
- Coord, &dwWritten);
- GetConsoleScreenBufferInfo(hConsole, &ConsoleInfo);
- }
- // Inserts blank lines to the cursor-y-position
- // scrolls down the rest. CURSOR MOVEMENT (to Col#1) ???
- void TConsole::InsertLine(int numlines)
- {
- COORD to;
- SMALL_RECT from;
- SMALL_RECT clip;
- CHAR_INFO fill;
- int acty;
-
- // Rest of screen would be deleted
- if ( (acty = GetCursorY()) >= CON_LINES - numlines ) {
- ClearEOScreen(); // delete rest of screen
- return;
- } /* IF */
-
- // Else scroll down the part of the screen which is below the
- // cursor.
- from.Left = CON_LEFT;
- from.Top = CON_TOP + (SHORT)acty;
- from.Right = CON_LEFT + (SHORT)CON_COLS;
- from.Bottom = CON_TOP + (SHORT)CON_LINES;
-
- clip = from;
- to.X = 0;
- to.Y = (SHORT)(from.Top + numlines);
-
- fill.Char.AsciiChar = ' ';
- fill.Attributes = 7; // WHICH ATTRIBUTES TO TAKE FOR BLANK LINE ??
-
- ScrollConsoleScreenBuffer(hConsole, &from, &clip, to, &fill);
- } /* InsertLine */
- // Inserts blank characters under the cursor
- void TConsole::InsertCharacter(int numchar)
- {
- int actx;
- SMALL_RECT from;
- SMALL_RECT clip;
- COORD to;
- CHAR_INFO fill;
-
- if ( (actx = GetCursorX()) >= CON_COLS - numchar ) {
- ClearEOLine();
- return;
- } /* IF */
-
- from.Left = CON_LEFT + (SHORT)actx;
- from.Top = CON_TOP + (SHORT)GetCursorY();
- from.Right = CON_LEFT + (SHORT)CON_COLS;
- from.Bottom = CON_TOP + (SHORT)from.Top;
-
- clip = from;
- to.X = (SHORT)(actx + numchar);
- to.Y = from.Top;
-
- fill.Char.AsciiChar = ' ';
- fill.Attributes = wAttributes; // WHICH ATTRIBUTES TO TAKE FOR BLANK CHAR ??
-
- ScrollConsoleScreenBuffer(hConsole, &from, &clip, to, &fill);
- } /* InsertCharacter */
- // Deletes characters under the cursor
- // Note that there are cases in which all the following lines should shift by
- // a character, but we don't handle these. This could break some
- // VT102-applications, but it shouldn't be too much of an issue.
- void TConsole::DeleteCharacter(int numchar)
- {
- int actx;
- SMALL_RECT from;
- SMALL_RECT clip;
- COORD to;
- CHAR_INFO fill;
-
- if ( (actx = GetCursorX()) >= CON_COLS - numchar ) {
- ClearEOLine();
- return;
- } /* IF */
-
- from.Left = CON_LEFT + (SHORT)actx;
- from.Top = CON_TOP + (SHORT)GetCursorY();
- from.Right = CON_LEFT + (SHORT)CON_COLS;
- from.Bottom = CON_TOP + from.Top;
-
- clip = from;
- to.X = (SHORT)(actx - numchar);
- to.Y = from.Top;
-
- fill.Char.AsciiChar = ' ';
- fill.Attributes = wAttributes; // WHICH ATTRIBUTES TO TAKE FOR BLANK CHAR ??
-
- ScrollConsoleScreenBuffer(hConsole, &from, &clip, to, &fill);
- } /* DeleteCharacter */
- void TConsole::SetRawCursorPosition(int x, int y) {
- if (x > CON_WIDTH) x = CON_WIDTH;
- if (x < 0) x = 0;
- if (y > CON_HEIGHT) y = CON_HEIGHT;
- if (y < 0) y = 0;
- COORD Coord = {(short)(CON_LEFT + x), (short)(CON_TOP + y)};
- SetConsoleCursorPosition(hConsole, Coord);
-
- // Update the ConsoleInfo struct (Paul Brannan 5/9/98)
- ConsoleInfo.dwCursorPosition.Y = Coord.Y;
- ConsoleInfo.dwCursorPosition.X = Coord.X;
-
- // bug fix in case we went too far (Paul Brannan 5/25/98)
- if(ConsoleInfo.dwCursorPosition.X < CON_LEFT)
- ConsoleInfo.dwCursorPosition.X = CON_LEFT;
- if(ConsoleInfo.dwCursorPosition.X > CON_RIGHT)
- ConsoleInfo.dwCursorPosition.X = CON_RIGHT;
- if(ConsoleInfo.dwCursorPosition.Y < CON_TOP)
- ConsoleInfo.dwCursorPosition.Y = CON_TOP;
- if(ConsoleInfo.dwCursorPosition.Y > CON_BOTTOM)
- ConsoleInfo.dwCursorPosition.Y = CON_BOTTOM;
- }
- // The new SetCursorPosition takes scroll regions into consideration
- // (Paul Brannan 6/27/98)
- void TConsole::SetCursorPosition(int x, int y) {
- if (x > CON_WIDTH) x = CON_WIDTH;
- if (x < 0) x = 0;
- if(iScrollEnd != -1) {
- if(y > iScrollEnd) y = iScrollEnd;
- } else {
- if(y > CON_HEIGHT) y = CON_HEIGHT;
- }
- if(iScrollStart != -1) {
- if(y < iScrollStart) y = iScrollStart;
- } else {
- if(y < 0) y = 0;
- }
- COORD Coord = {(short)(CON_LEFT + x), (short)(CON_TOP + y)};
- SetConsoleCursorPosition(hConsole, Coord);
-
- // Update the ConsoleInfo struct
- ConsoleInfo.dwCursorPosition.Y = Coord.Y;
- ConsoleInfo.dwCursorPosition.X = Coord.X;
- }
- void TConsole::MoveCursorPosition(int x, int y) {
- SetCursorPosition(CON_CUR_X + x, CON_CUR_Y + y);
- }
- void TConsole::SetExtendedMode(int iFunction, BOOL bEnable)
- {
- // Probably should do something here...
- // Should change the screen mode, but do we need this?
- }
- void TConsole::SetScroll(int start, int end) {
- iScrollStart = start;
- iScrollEnd = end;
- }
- void TConsole::Beep() {
- if(ini.get_do_beep()) {
- if(!ini.get_speaker_beep()) printit("a");
- else ::Beep(400, 100);
- }
- }
- void TConsole::SetCursorSize(int pct) {
- CONSOLE_CURSOR_INFO ci = {(pct != 0)?pct:1, pct != 0};
- SetConsoleCursorInfo(hConsole, &ci);
- }
- void saveScreen(CHAR_INFO *chiBuffer) {
- HANDLE hStdout;
- CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
- SMALL_RECT srctReadRect;
- COORD coordBufSize;
- COORD coordBufCoord;
-
- hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
- GetConsoleScreenBufferInfo(hStdout, &ConsoleInfo);
-
- srctReadRect.Top = CON_TOP; /* top left: row 0, col 0 */
- srctReadRect.Left = CON_LEFT;
- srctReadRect.Bottom = CON_BOTTOM; /* bot. right: row 1, col 79 */
- srctReadRect.Right = CON_RIGHT;
-
- coordBufSize.Y = CON_BOTTOM-CON_TOP+1;
- coordBufSize.X = CON_RIGHT-CON_LEFT+1;
-
- coordBufCoord.X = CON_TOP;
- coordBufCoord.Y = CON_LEFT;
-
- ReadConsoleOutput(
- hStdout, /* screen buffer to read from */
- chiBuffer, /* buffer to copy into */
- coordBufSize, /* col-row size of chiBuffer */
-
- coordBufCoord, /* top left dest. cell in chiBuffer */
- &srctReadRect); /* screen buffer source rectangle */
- }
- void restoreScreen(CHAR_INFO *chiBuffer) {
- HANDLE hStdout;
- CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
- SMALL_RECT srctReadRect;
- COORD coordBufSize;
- COORD coordBufCoord;
-
- hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
- GetConsoleScreenBufferInfo(hStdout, &ConsoleInfo);
-
- // restore screen
- srctReadRect.Top = CON_TOP; /* top left: row 0, col 0 */
- srctReadRect.Left = CON_LEFT;
- srctReadRect.Bottom = CON_BOTTOM; /* bot. right: row 1, col 79 */
- srctReadRect.Right = CON_RIGHT;
-
- coordBufSize.Y = CON_BOTTOM-CON_TOP+1;
- coordBufSize.X = CON_RIGHT-CON_LEFT+1;
-
- coordBufCoord.X = CON_TOP;
- coordBufCoord.Y = CON_LEFT;
- WriteConsoleOutput(
- hStdout, /* screen buffer to write to */
- chiBuffer, /* buffer to copy from */
- coordBufSize, /* col-row size of chiBuffer */
- coordBufCoord, /* top left src cell in chiBuffer */
- &srctReadRect); /* dest. screen buffer rectangle */
- // end restore screen
-
- }
- CHAR_INFO* newBuffer() {
- CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
- HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
- GetConsoleScreenBufferInfo(hStdout, &ConsoleInfo);
- CHAR_INFO * chiBuffer;
- chiBuffer = new CHAR_INFO[(CON_BOTTOM-CON_TOP+1)*(CON_RIGHT-CON_LEFT+1)];
- return chiBuffer;
- }
- void deleteBuffer(CHAR_INFO* chiBuffer) {
- delete[] chiBuffer;
- }