ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

tconsole.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:      tconsole.cpp
00029 //
00030 // Contents:    screen functions
00031 //
00032 // Product:     telnet
00033 //
00034 //
00035 // Revisions: Mar. 29, 2000 pbranna@clemson (Paul Brannan)
00036 //            June 15, 1998 pbranna@clemson.edu
00037 //            May 16, 1998  pbranna@clemson.edu
00038 //            05. Sep.1997  roryt@hol.gr (I.Ioannou)
00039 //            11.May,1997   roryt@hol.gr
00040 //            06.April,1997 roryt@hol.gr
00041 //            30.M„rz.1997  Titus_Boxberg@public.uni-hamburg.de
00042 //            5.Dec.1996    jbj@nounname.com
00043 //            Version 2.0
00044 //            02.Apr.1995   igor.milavec@uni-lj.si
00045 //                    Original code
00046 //
00048 
00049 #include "precomp.h"
00050 
00051 // argsused doesn't work on MSVC++
00052 #ifdef __BORLANDC__
00053 #pragma argsused
00054 #endif
00055 
00056 TConsole::TConsole(HANDLE h) {
00057     hConsole = h;
00058 
00059     GetConsoleScreenBufferInfo(hConsole, &ConsoleInfo);
00060 
00061     // Start with correct colors
00062     int color_fg = ini.get_normal_fg();
00063     int color_bg = ini.get_normal_bg();
00064     if(color_fg == -1)
00065         color_fg = defaultfg = origfg = ConsoleInfo.wAttributes & 0xF;
00066     else
00067         defaultfg = origfg = color_fg;
00068     if(color_bg == -1)
00069         color_bg = defaultbg = origbg = (ConsoleInfo.wAttributes >> 4) & 0xF;
00070     else
00071         defaultbg = origbg = color_bg;
00072     wAttributes = color_fg | (color_bg << 4);
00073     reverse = blink = underline = false;
00074     SetConsoleTextAttribute(hConsole, wAttributes);
00075 
00076     insert_mode = 0;
00077 
00078     // Set the screen size
00079     SetWindowSize(ini.get_term_width(), ini.get_term_height());
00080 
00081     iScrollStart = -1;
00082     iScrollEnd = -1;
00083 }
00084 
00085 TConsole::~TConsole() {
00086     wAttributes = origfg | (origbg << 4);
00087     SetCursorPosition(0, CON_HEIGHT);
00088     SetConsoleTextAttribute(hConsole, wAttributes);
00089     WriteCtrlChar('\x0a');
00090 }
00091 
00092 // Paul Brannan 8/2/98
00093 void TConsole::SetWindowSize(int width, int height) {
00094     SMALL_RECT sr = {
00095         CON_LEFT,
00096         CON_TOP,
00097         (width == -1) ? CON_RIGHT : CON_LEFT + width - 1,
00098         (height == -1) ? CON_BOTTOM : CON_TOP + height - 1
00099     };
00100     ConsoleInfo.dwSize.X = width;
00101     if(ConsoleInfo.dwSize.Y < height) ConsoleInfo.dwSize.Y = height;
00102     SetConsoleScreenBufferSize(hConsole, ConsoleInfo.dwSize);
00103     SetConsoleWindowInfo(hConsole, TRUE, &sr);
00104     SetConsoleScreenBufferSize(hConsole, ConsoleInfo.dwSize);
00105     sync();
00106 }
00107 
00108 // Paul Brannan 5/15/98
00109 void TConsole::sync() {
00110     GetConsoleScreenBufferInfo(hConsole, &ConsoleInfo);
00111 }
00112 
00113 void TConsole::HighVideo() {
00114     wAttributes = wAttributes | (unsigned char) 8;
00115 }
00116 
00117 void TConsole::LowVideo() {
00118     wAttributes = wAttributes & (unsigned char) (0xff-8);
00119 }
00120 
00121 void TConsole::Normal() {
00122     // I.Ioannou 11 May 1997
00123     // Color 7 is correct on some systems (for example Linux)
00124     // but not with others (for example SCO)
00125     // we must preserve the colors :
00126     // 06/04/98 thanks to Paul a .ini parameter from now on
00127 
00128     BlinkOff();
00129     UnderlineOff();
00130     if(ini.get_preserve_colors()) {
00131         ReverseOff();
00132         LowVideo();
00133     } else {
00134         fg = defaultfg;
00135         bg = defaultbg;
00136         wAttributes = (unsigned char)fg | (bg << 4);
00137         reverse = false;
00138     }
00139 }
00140 
00141 void TConsole::SetForeground(unsigned char wAttrib) {
00142     if(reverse) bg = wAttrib; else fg = wAttrib;
00143     wAttributes = (wAttributes & (unsigned char)0x88) |
00144         (unsigned char)fg | (bg << 4);
00145 }
00146 
00147 void TConsole::SetBackground(unsigned char wAttrib) {
00148     if(reverse) fg = wAttrib; else bg = wAttrib;
00149     wAttributes = (wAttributes & (unsigned char)0x88) |
00150         (unsigned char)fg | (bg << 4);
00151 }
00152 
00153 // As far as I can tell, there's no such thing as blink in Windows Console.
00154 // I tried using some inline asm to turn off high-intensity backgrounds,
00155 // but I got a BSOD.  Perhaps there is an undocumented function?
00156 // (Paul Brannan 6/27/98)
00157 void TConsole::BlinkOn() {
00158     blink = 1;
00159     if(underline) {
00160         UlBlinkOn();
00161     } else {
00162         if(ini.get_blink_bg() != -1) {
00163             wAttributes &= 0x8f;                    // turn off bg
00164             wAttributes |= ini.get_blink_bg() << 4;
00165         }
00166         if(ini.get_blink_fg() != -1) {
00167             wAttributes &= 0xf8;                    // turn off fg
00168             wAttributes |= ini.get_blink_fg();
00169         }
00170         if(ini.get_blink_bg() == -1 && ini.get_blink_fg() == -1)
00171             wAttributes |= 0x80;
00172     }
00173 }
00174 
00175 // Added by I.Ioannou 06 April, 1997
00176 void TConsole::BlinkOff() {
00177     blink = 0;
00178     if(underline) {
00179         UlBlinkOff();
00180     } else {
00181         if(ini.get_blink_bg() != -1) {
00182             wAttributes &= 0x8f;                    // turn off bg
00183             wAttributes |= defaultbg << 4;
00184         }
00185         if(ini.get_blink_fg() != -1) {
00186             wAttributes &= 0xf8;                    // turn off fg
00187             wAttributes |= defaultfg;
00188         }
00189         if(ini.get_blink_bg() == -1 && ini.get_blink_fg() == -1)
00190             wAttributes &= 0x7f;
00191     }
00192 }
00193 
00194 // Paul Brannan 6/27/98
00195 void TConsole::UnderlineOn() {
00196     underline = 1;
00197     if(blink) {
00198         UlBlinkOn();
00199     } else {
00200         if(ini.get_underline_bg() != -1) {
00201             wAttributes &= 0x8f;                    // turn off bg
00202             wAttributes |= ini.get_underline_bg() << 4;
00203         }
00204         if(ini.get_underline_fg() != -1) {
00205             wAttributes &= 0xf8;                    // turn off fg
00206             wAttributes |= ini.get_underline_fg();
00207         }
00208         if(ini.get_underline_bg() == -1 && ini.get_underline_fg() == -1)
00209             wAttributes |= 0x80;
00210     }
00211 }
00212 
00213 // Paul Brannan 6/27/98
00214 void TConsole::UnderlineOff() {
00215     underline = 0;
00216     if(blink) {
00217         UlBlinkOff();
00218     } else {
00219         if(ini.get_blink_bg() != -1) {
00220             wAttributes &= 0x8f;                    // turn off bg
00221             wAttributes |= defaultbg << 4;
00222         }
00223         if(ini.get_blink_fg() != -1) {
00224             wAttributes &= 0xf8;                    // turn off fg
00225             wAttributes |= defaultfg;
00226         }
00227         if(ini.get_blink_bg() == -1 && ini.get_blink_fg() == -1)
00228             wAttributes &= 0x7f;
00229     }
00230 }
00231 
00232 // Paul Brannan 6/27/98
00233 void TConsole::UlBlinkOn() {
00234     if(ini.get_ulblink_bg() != -1) {
00235         wAttributes &= 0x8f;                    // turn off bg
00236         wAttributes |= ini.get_ulblink_bg() << 4;
00237     }
00238     if(ini.get_ulblink_fg() != -1) {
00239         wAttributes &= 0xf8;                    // turn off fg
00240         wAttributes |= ini.get_ulblink_fg();
00241     }
00242     if(ini.get_ulblink_bg() == -1 && ini.get_ulblink_fg() == -1)
00243         wAttributes |= 0x80;
00244 }
00245 
00246 // Paul Brannan 6/27/98
00247 void TConsole::UlBlinkOff() {
00248     if(blink) {
00249         BlinkOn();
00250     } else if(underline) {
00251         UnderlineOn();
00252     } else {
00253         Normal();
00254     }
00255 }
00256 
00257 // Paul Brannan 6/26/98
00258 void TConsole::Lightbg() {
00259     WORD *pAttributes = new WORD[CON_COLS];
00260     DWORD Result;
00261 
00262     // Paul Brannan 8/5/98
00263     // Correction: processing more than one line at a time causes a segfault
00264     // if the screen width != 80
00265     for(int i = CON_TOP; i <= CON_BOTTOM; i++) {
00266         COORD Coord = {CON_LEFT, i};
00267 
00268         ReadConsoleOutputAttribute(hConsole, pAttributes, (DWORD)(CON_COLS),
00269             Coord, &Result);
00270 
00271         for(DWORD j = 0; j < Result; j++) pAttributes[j] |= 0x80;
00272 
00273         WriteConsoleOutputAttribute(hConsole, pAttributes, Result, Coord,
00274             &Result);
00275     }
00276 
00277     delete[] pAttributes; // clean up
00278 
00279     wAttributes |= (unsigned char)0x80;
00280     bg |= 8;
00281 }
00282 
00283 // Paul Brannan 6/26/98
00284 void TConsole::Darkbg() {
00285     WORD *pAttributes = new WORD[CON_COLS];
00286     DWORD Result;
00287 
00288     // Paul Brannan 8/5/98
00289     // Correction: processing more than one line at a time causes a segfault
00290     // if the screen width != 80
00291     for(int i = CON_TOP; i <= CON_BOTTOM; i++) {
00292         COORD Coord = {CON_LEFT, i};
00293 
00294         ReadConsoleOutputAttribute(hConsole, pAttributes, (DWORD)(CON_COLS),
00295             Coord, &Result);
00296 
00297         for(DWORD j = 0; j < Result; j++) pAttributes[j] &= 0x7f;
00298 
00299         WriteConsoleOutputAttribute(hConsole, pAttributes, Result, Coord,
00300             &Result);
00301     }
00302 
00303     delete[] pAttributes; // clean up
00304 
00305 
00306     wAttributes &= (unsigned char)0x7f;
00307     bg &= 7;
00308 }
00309 
00310 // Added by I.Ioannou 11.May,1997
00311 void TConsole::ReverseOn() {
00312     if (!reverse) {
00313         reverse = true;
00314 
00315         // atl  : forground attributes without the intensity
00316         // ath  : backgound attributes without the blink
00317         // bl   : the blink state
00318         // ints : the intensity
00319         unsigned char atl   = wAttributes & (unsigned char) 0x07;
00320         unsigned char ath   = wAttributes & (unsigned char) 0x70;
00321         unsigned char bl    = wAttributes & (unsigned char) 0x80;
00322         unsigned char ints  = wAttributes & (unsigned char) 0x08;
00323         wAttributes = bl | (atl << 4) | ints | (ath >> 4);
00324     }
00325 }
00326 
00327 // Added by I.Ioannou 11.May,1997
00328 void TConsole::ReverseOff() {
00329     if (reverse) {
00330         reverse = false;
00331         wAttributes = fg | (bg << 4);
00332     }
00333 }
00334 
00335 unsigned long TConsole::WriteText(const char *pszString, unsigned long cbString) {
00336     DWORD Result;
00337 
00338     if(insert_mode) {
00339         InsertCharacter(cbString);
00340     }
00341 
00342     WriteConsoleOutputCharacter(hConsole, (char *)pszString, cbString,
00343         ConsoleInfo.dwCursorPosition, &Result);
00344     FillConsoleOutputAttribute(hConsole, wAttributes, cbString,
00345         ConsoleInfo.dwCursorPosition, &Result);
00346     return Result;
00347 }
00348 
00349 // Formerly ConWriteString (Paul Brannan 6/28/98)
00350 unsigned long TConsole::WriteStringFast(const char* pszString, unsigned long cbString) {
00351     DWORD Result;
00352 
00353     SetConsoleTextAttribute(hConsole, wAttributes);
00354 
00355     //check to see if the line is longer than the display
00356     if (!getLineWrap() && ((unsigned)CON_CUR_X + cbString) >= (unsigned)CON_COLS) {
00357         // Take care of the last line last colum exception...
00358         // The display scrolls up if you use the normal char out
00359         //   function even if you only write to the last place
00360         //   on the line. :-(
00361         if ((unsigned)CON_CUR_Y >= (unsigned)CON_HEIGHT) {
00362             unsigned long iFakeResult = cbString;
00363             cbString = CON_COLS - CON_CUR_X - 1;
00364 
00365             // FIX ME !!! This will avoid the exception when cbString
00366             // is <= 0 but still doesn't work :-(
00367             if (cbString > 0)
00368                 WriteConsole(hConsole, pszString, cbString, &Result, 0);
00369 
00370             COORD dwBufferCoord;
00371             dwBufferCoord.X = 0;
00372             dwBufferCoord.Y = 0;
00373 
00374             CHAR_INFO ciBuffer;
00375             ciBuffer.Char.AsciiChar = *(pszString+cbString);
00376             ciBuffer.Attributes = wAttributes;
00377             SMALL_RECT srWriteRegion;
00378             srWriteRegion.Top =     (SHORT) CON_BOTTOM;
00379             srWriteRegion.Bottom =  (SHORT) CON_BOTTOM;
00380             srWriteRegion.Left =    (SHORT) CON_RIGHT;
00381             srWriteRegion.Right =   (SHORT) CON_RIGHT;
00382 
00383             COORD bufSize = {1,1};
00384 
00385             WriteConsoleOutput(hConsole, &ciBuffer, bufSize,
00386                 dwBufferCoord, &srWriteRegion);
00387 
00388             // We need to update the ConsoleInfo struct now (Paul Brannan 5/9/98)
00389             ConsoleInfo.dwCursorPosition.X = CON_RIGHT;
00390 
00391             return iFakeResult; // Skip the chars that did not fit
00392         }
00393         // just write the line up to the end
00394         else {
00395             int iFakeResult = cbString;
00396             cbString = CON_COLS - CON_CUR_X;
00397 
00398             if(cbString > 0) {
00399                 WriteConsole(hConsole, pszString, cbString, &Result, 0);
00400 
00401                 // We need to update the ConsoleInfo struct now (Paul Brannan 5/9/98)
00402                 ConsoleInfo.dwCursorPosition.X += (unsigned short)Result;
00403             }
00404 
00405             return iFakeResult; // Skip the chars that did not fit
00406         }
00407     } else {
00408         // If custom scrolling is enabled we must take care of it
00409         if(iScrollStart != -1 || iScrollEnd != -1) {
00410             return WriteString(pszString, cbString);
00411         }
00412 
00413         // Apparently VT100 terminals have an invisible "81st" column that
00414         // can hold a cursor until another character is printed.  I'm not sure
00415         // exactly how to handle this, but here's a hack (Paul Brannan 5/28/98)
00416         if(ini.get_vt100_mode() && cbString + (unsigned)CON_CUR_X == (unsigned)CON_COLS) {
00417 
00418             cbString--;
00419             if((long)cbString >= 0) WriteConsole(hConsole, pszString, cbString, &Result, 0);
00420 
00421             COORD dwBufferCoord;
00422             dwBufferCoord.X = 0;
00423             dwBufferCoord.Y = 0;
00424 
00425             CHAR_INFO ciBuffer;
00426             ciBuffer.Char.AsciiChar = *(pszString+cbString);
00427             ciBuffer.Attributes = wAttributes;
00428             SMALL_RECT srWriteRegion;
00429             srWriteRegion.Top =    (SHORT) ConsoleInfo.dwCursorPosition.Y;
00430             srWriteRegion.Bottom = (SHORT) ConsoleInfo.dwCursorPosition.Y;
00431             srWriteRegion.Left =   (SHORT) CON_RIGHT;
00432             srWriteRegion.Right =  (SHORT) CON_RIGHT;
00433 
00434             COORD bufSize = {1,1};
00435 
00436             WriteConsoleOutput(hConsole, &ciBuffer, bufSize,
00437                 dwBufferCoord, &srWriteRegion);
00438 
00439             // Update the ConsoleInfo struct
00440             ConsoleInfo.dwCursorPosition.X = CON_RIGHT + 1;
00441 
00442             return Result + 1;
00443         }
00444 
00445         // normal line will wrap normally or not to the end of buffer
00446         WriteConsole(hConsole, pszString, cbString, &Result, 0);
00447 
00448         // We need to update the ConsoleInfo struct now (Paul Brannan 5/9/98)
00449         // FIX ME!!! This is susceptible to the same problem as above.
00450         // (e.g. we write out 160 characters)
00451         ConsoleInfo.dwCursorPosition.X += (unsigned short)Result;
00452         while(CON_CUR_X > CON_WIDTH) {
00453             ConsoleInfo.dwCursorPosition.X -= ConsoleInfo.dwSize.X;
00454             if((unsigned)CON_CUR_Y < (unsigned)CON_HEIGHT) {
00455                 ConsoleInfo.dwCursorPosition.Y++;
00456             } else {
00457                 // If we aren't at the bottom of the window, then we need to
00458                 // scroll down (Paul Brannan 4/14/2000)
00459                 if(ConsoleInfo.srWindow.Bottom < ConsoleInfo.dwSize.Y - 1) {
00460                     ConsoleInfo.srWindow.Top++;
00461                     ConsoleInfo.srWindow.Bottom++;
00462                     ConsoleInfo.dwCursorPosition.Y++;
00463                     SetConsoleWindowInfo(hConsole, TRUE, &ConsoleInfo.srWindow);
00464                 }
00465             }
00466         }
00467     }
00468 
00469     return Result;
00470 
00471 }
00472 
00473 unsigned long TConsole::WriteString(const char* pszString, unsigned long cbString) {
00474     DWORD Result = 0;
00475 
00476     SetConsoleTextAttribute(hConsole, wAttributes);
00477 
00478     //check to see if the line is longer than the display
00479     if (!getLineWrap()){
00480         unsigned long iFakeResult = cbString;
00481         if((CON_CUR_X + cbString) >= (unsigned int)CON_COLS)
00482             cbString = CON_COLS - CON_CUR_X;
00483         if(cbString > 0)
00484             Result = WriteText(pszString, cbString);
00485 
00486         // We need to update the ConsoleInfo struct now (Paul Brannan 5/9/98)
00487         ConsoleInfo.dwCursorPosition.X += (unsigned short)Result;
00488         SetConsoleCursorPosition(hConsole, ConsoleInfo.dwCursorPosition);
00489 
00490         return iFakeResult; // Skip the chars that did not fit
00491     } else {
00492         // Write up to the end of the line
00493         unsigned long temp = cbString;
00494         if((CON_CUR_X + temp) > (unsigned int)CON_COLS) {
00495             temp = CON_COLS - CON_CUR_X;
00496         } else {
00497             Result = WriteText(pszString, temp);
00498             ConsoleInfo.dwCursorPosition.X += (unsigned short)Result;
00499             SetConsoleCursorPosition(hConsole, ConsoleInfo.dwCursorPosition);
00500             return Result;
00501         }
00502         if(temp > 0) {
00503             Result = WriteText(pszString, temp);
00504             ConsoleInfo.dwCursorPosition.X += (unsigned short)Result;
00505             temp = (unsigned short)Result;
00506         }
00507 
00508         // keep writing lines until we get to less than 80 chars left
00509         while((temp + (unsigned int)CON_COLS) < cbString) {
00510             index(); // LF
00511             ConsoleInfo.dwCursorPosition.X = 0; // CR
00512             Result = WriteText(&pszString[temp], CON_COLS);
00513             temp += (unsigned short)Result;
00514         }
00515 
00516         // write out the last bit
00517         if(temp < cbString) {
00518             index();
00519             ConsoleInfo.dwCursorPosition.X = 0;
00520             Result = WriteText(&pszString[temp], cbString - temp);
00521             temp += (unsigned short)Result;
00522         }
00523 
00524         // Apparently VT100 terminals have an invisible "81st" column that
00525         // can hold a cursor until another character is printed.  I'm not sure
00526         // exactly how to handle this, but here's a hack (Paul Brannan 5/28/98)
00527         if(!ini.get_vt100_mode() && cbString + (unsigned)ConsoleInfo.dwCursorPosition.X
00528             == (unsigned int)CON_COLS) {
00529             index();
00530             ConsoleInfo.dwCursorPosition.X = 0;
00531         }
00532 
00533         SetConsoleCursorPosition(hConsole, ConsoleInfo.dwCursorPosition);
00534 
00535         return temp;
00536     }
00537 
00538     return 0;
00539 }
00540 
00541 // This is for multi-character control strings (Paul Brannan 6/26/98)
00542 unsigned long TConsole::WriteCtrlString(const char *pszString, unsigned long cbString) {
00543     unsigned long total = 0;
00544     while(total < cbString) {
00545         unsigned long Result = WriteCtrlChar(*(pszString + total));
00546         if(Result == 0) {
00547             Result = WriteStringFast(pszString + total, 1);
00548             if(Result == 0) return total;
00549         }
00550         total += Result;
00551     }
00552     return total;
00553 }
00554 
00555 // This is for printing single control characters
00556 // WriteCtrlString uses this (Paul Brannan 6/26/98)
00557 unsigned long TConsole::WriteCtrlChar(char c) {
00558     // The console does not handel the CR/LF chars as we might expect
00559     // when using color. The attributes are not set correctly, so we
00560     // must interpret them manualy to preserve the colors on the screen.
00561 
00562     unsigned long Result = 0; // just in case (Paul Brannan 6/26/98)
00563     switch (c) {
00564     case '\x09': // horizontal tab
00565         SetCursorPosition((((CON_CUR_X/8)+1)*8), CON_CUR_Y);
00566         Result = 1;
00567         break;
00568 
00569     case '\x0a': // line feed
00570         index();
00571         Result = 1;
00572         break;
00573     case '\x0d': // carrage return
00574         SetCursorPosition(CON_LEFT, CON_CUR_Y); // move to beginning of line
00575         Result = 1;
00576         break;
00577     case '\b': // backspace
00578         // Added support for backspace so the cursor position can be changed
00579         // (Paul Brannan 5/25/98)
00580         MoveCursorPosition(-1, 0);
00581         Result = 1;
00582     default :    // else just write it like normal
00583         break;
00584     }
00585 
00586     return Result;
00587 }
00588 
00589 void TConsole::index() {
00590     // if on the last line scroll up
00591     // This must work with scrolling (Paul Brannan 5/13/98)
00592     if(iScrollEnd != -1 && (signed)CON_CUR_Y >= iScrollEnd) {
00593         ScrollDown(iScrollStart, iScrollEnd, -1);
00594     } else if ((iScrollEnd == -1 && (signed)CON_CUR_Y >= (signed)CON_HEIGHT)) {
00595         DWORD Result;
00596         WriteConsole(hConsole, "\n", 1, &Result, NULL);
00597 
00598         // If we aren't at the bottom of the buffer, then we need to
00599         // scroll down (Paul Brannan 4/14/2000)
00600         if(iScrollEnd == -1 && ConsoleInfo.srWindow.Bottom < ConsoleInfo.dwSize.Y - 1) {
00601             ConsoleInfo.srWindow.Top++;
00602             ConsoleInfo.srWindow.Bottom++;
00603             ConsoleInfo.dwCursorPosition.Y++;
00604             // SetConsoleWindowInfo(hConsole, TRUE, &ConsoleInfo.srWindow);
00605         } else {
00606             ClearLine();
00607         }
00608     } else {     // else move cursor down to the next line
00609         SetCursorPosition(CON_CUR_X, CON_CUR_Y + 1);
00610     }
00611 }
00612 
00613 void TConsole::reverse_index() {
00614     // if on the top line scroll down
00615     // This must work with scrolling (Paul Brannan 5/13/98)
00616     // We should be comparing against iScrollStart, not iScrollEnd (PB 12/2/98)
00617     if (iScrollStart == -1 && (signed)CON_CUR_Y <= 0) {
00618         ScrollDown(iScrollStart, -1, 1);
00619     } else if (iScrollStart != -1 && (signed)CON_CUR_Y <= iScrollStart) {
00620             ScrollDown(iScrollStart, iScrollEnd, 1);
00621     } else       // else move cursor up to the previous line
00622         SetCursorPosition(CON_CUR_X,CON_CUR_Y - 1);
00623 }
00624 
00625 void TConsole::ScrollDown( int iStartRow , int iEndRow, int bUp ){
00626     CHAR_INFO ciChar;
00627     SMALL_RECT srScrollWindow;
00628 
00629     // Correction from I.Ioannou 11 May 1997
00630     // check the scroll region
00631     if (iStartRow < iScrollStart) iStartRow = iScrollStart;
00632 
00633     // Correction from I.Ioannou 11 May 1997
00634     // this will make Top the CON_TOP
00635     if ( iStartRow == -1) iStartRow = 0;
00636 
00637     // Correction from I.Ioannou 18 Aug 97
00638     if ( iEndRow == -1) {
00639         if ( iScrollEnd == -1 )
00640             iEndRow = CON_HEIGHT;
00641         else
00642             iEndRow = ((CON_HEIGHT <= iScrollEnd) ? CON_HEIGHT : iScrollEnd);
00643     }
00644     //
00645 
00646     if ( iStartRow > CON_HEIGHT) iStartRow = CON_HEIGHT;
00647     if ( iEndRow > CON_HEIGHT) iEndRow = CON_HEIGHT;
00648 
00649     srScrollWindow.Left =           (CON_LEFT);
00650     srScrollWindow.Right =  (SHORT) (CON_RIGHT);
00651     srScrollWindow.Top =    (SHORT) (CON_TOP + iStartRow );
00652     srScrollWindow.Bottom = (SHORT) (CON_TOP + iEndRow); // don't subtract 1 (PB 5/28)
00653 
00654     ciChar.Char.AsciiChar = ' ';           // fill with spaces
00655     ciChar.Attributes = wAttributes;       // fill with current attrib
00656 
00657     // This should speed things up (Paul Brannan 9/2/98)
00658     COORD dwDestOrg = {srScrollWindow.Left, srScrollWindow.Top + bUp};
00659 
00660     // Note that iEndRow and iStartRow had better not be equal to -1 at this
00661     // point.  There are four cases to consider for out of bounds.  Two of
00662     // these cause the scroll window to be cleared; the others cause the
00663     // scroll region to be modified.  (Paul Brannan 12/3/98)
00664     if(dwDestOrg.Y > CON_TOP + iEndRow) {
00665         // We are scrolling past the end of the scroll region, so just
00666         // clear the window instead (Paul Brannan 12/3/98)
00667         ClearWindow(CON_TOP + iStartRow, CON_TOP + iEndRow);
00668         return;
00669     } else if(dwDestOrg.Y + (iEndRow-iStartRow+1) < CON_TOP + iStartRow) {
00670         // We are scrolling past the end of the scroll region, so just
00671         // clear the window instead (Paul Brannan 12/3/98)
00672         ClearWindow(CON_TOP + iStartRow, CON_TOP + iEndRow);
00673         return;
00674     } else if(dwDestOrg.Y < CON_TOP + iStartRow) {
00675         // Modify the scroll region (Paul Brannan 12/3/98)
00676         dwDestOrg.Y = CON_TOP + iStartRow;
00677         srScrollWindow.Top -= bUp;
00678     } else  if(dwDestOrg.Y + (iEndRow-iStartRow+1) > CON_TOP + iEndRow) {
00679         // Modify the scroll region (Paul Brannan 12/3/98)
00680         srScrollWindow.Bottom -= bUp;
00681     }
00682 
00683     ScrollConsoleScreenBuffer(hConsole, &srScrollWindow,
00684         0, dwDestOrg, &ciChar);
00685 }
00686 
00687 // This allows us to clear the screen with an arbitrary character
00688 // (Paul Brannan 6/26/98)
00689 void TConsole::ClearScreen(char c) {
00690     DWORD dwWritten;
00691     COORD Coord = {CON_LEFT, CON_TOP};
00692     FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_COLS)*
00693         (DWORD)(CON_LINES), Coord, &dwWritten);
00694     FillConsoleOutputAttribute(hConsole, wAttributes, (DWORD)(CON_COLS)*
00695         (DWORD)(CON_LINES), Coord, &dwWritten);
00696 }
00697 
00698 // Same as clear screen, but only affects the scroll region
00699 void TConsole::ClearWindow(int iStartRow, int iEndRow, char c) {
00700     DWORD dwWritten;
00701     COORD Coord = {CON_LEFT, CON_TOP + iStartRow};
00702     FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_COLS)*
00703         (DWORD)(iEndRow-iStartRow+1), Coord, &dwWritten);
00704     FillConsoleOutputAttribute(hConsole, wAttributes, (DWORD)(CON_COLS)*
00705         (DWORD)(CON_LINES), Coord, &dwWritten);
00706 }
00707 
00708 // Clear from cursor to end of screen
00709 void TConsole::ClearEOScreen(char c)
00710 {
00711     DWORD dwWritten;
00712     COORD Coord = {CON_LEFT, CON_TOP + CON_CUR_Y + 1};
00713     FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_COLS)*
00714         (DWORD)(CON_HEIGHT - CON_CUR_Y), Coord, &dwWritten);
00715     FillConsoleOutputAttribute(hConsole, wAttributes, (DWORD)(CON_COLS)*
00716         (DWORD)(CON_LINES - CON_CUR_Y), Coord, &dwWritten);
00717     ClearEOLine();
00718 }
00719 
00720 // Clear from beginning of screen to cursor
00721 void TConsole::ClearBOScreen(char c)
00722 {
00723     DWORD dwWritten;
00724     COORD Coord = {CON_LEFT, CON_TOP};
00725     FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_COLS)*
00726         (DWORD)(CON_CUR_Y), Coord, &dwWritten);
00727     FillConsoleOutputAttribute(hConsole, wAttributes, (DWORD)(CON_COLS)*
00728         (DWORD)(CON_CUR_Y), Coord, &dwWritten);
00729     ClearBOLine();
00730 }
00731 
00732 void TConsole::ClearLine(char c)
00733 {
00734     DWORD dwWritten;
00735     COORD Coord = {CON_LEFT, CON_TOP + CON_CUR_Y};
00736     FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_COLS),
00737         Coord, &dwWritten);
00738     FillConsoleOutputAttribute(hConsole, wAttributes, (DWORD)(CON_COLS),
00739         Coord, &dwWritten);
00740     GetConsoleScreenBufferInfo(hConsole, &ConsoleInfo);
00741 }
00742 
00743 void TConsole::ClearEOLine(char c)
00744 {
00745     DWORD dwWritten;
00746     COORD Coord = {CON_LEFT + CON_CUR_X, CON_TOP + CON_CUR_Y};
00747     FillConsoleOutputAttribute(hConsole, wAttributes,
00748         (DWORD)(CON_RIGHT - CON_CUR_X) +1, Coord, &dwWritten);
00749     FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_RIGHT - CON_CUR_X) +1,
00750         Coord, &dwWritten);
00751     GetConsoleScreenBufferInfo(hConsole, &ConsoleInfo);
00752 }
00753 
00754 void TConsole::ClearBOLine(char c)
00755 {
00756     DWORD dwWritten;
00757     COORD Coord = {CON_LEFT, CON_TOP + CON_CUR_Y};
00758     FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_CUR_X) + 1, Coord,
00759         &dwWritten);
00760     FillConsoleOutputAttribute(hConsole, wAttributes, (DWORD)(CON_CUR_X) + 1,
00761         Coord, &dwWritten);
00762     GetConsoleScreenBufferInfo(hConsole, &ConsoleInfo);
00763 }
00764 
00765 
00766 //  Inserts blank lines to the cursor-y-position
00767 //  scrolls down the rest. CURSOR MOVEMENT (to Col#1) ???
00768 void TConsole::InsertLine(int numlines)
00769 {
00770     COORD       to;
00771     SMALL_RECT  from;
00772     SMALL_RECT  clip;
00773     CHAR_INFO       fill;
00774     int     acty;
00775 
00776     // Rest of screen would be deleted
00777     if ( (acty = GetCursorY()) >= CON_LINES - numlines ) {
00778         ClearEOScreen();    // delete rest of screen
00779         return;
00780     } /* IF */
00781 
00782     //  Else scroll down the part of the screen which is below the
00783     //  cursor.
00784     from.Left =     CON_LEFT;
00785     from.Top =      CON_TOP + (SHORT)acty;
00786     from.Right =    CON_LEFT + (SHORT)CON_COLS;
00787     from.Bottom =   CON_TOP + (SHORT)CON_LINES;
00788 
00789     clip = from;
00790     to.X = 0;
00791     to.Y = (SHORT)(from.Top + numlines);
00792 
00793     fill.Char.AsciiChar = ' ';
00794     fill.Attributes = 7;        // WHICH ATTRIBUTES TO TAKE FOR BLANK LINE ??
00795 
00796     ScrollConsoleScreenBuffer(hConsole, &from, &clip, to, &fill);
00797 } /* InsertLine */
00798 
00799 //  Inserts blank characters under the cursor
00800 void TConsole::InsertCharacter(int numchar)
00801 {
00802     int     actx;
00803     SMALL_RECT  from;
00804     SMALL_RECT  clip;
00805     COORD           to;
00806     CHAR_INFO       fill;
00807 
00808     if ( (actx = GetCursorX()) >= CON_COLS - numchar ) {
00809         ClearEOLine();
00810         return;
00811     } /* IF */
00812 
00813     from.Left =     CON_LEFT + (SHORT)actx;
00814     from.Top =      CON_TOP + (SHORT)GetCursorY();
00815     from.Right =    CON_LEFT + (SHORT)CON_COLS;
00816     from.Bottom =   CON_TOP + (SHORT)from.Top;
00817 
00818     clip = from;
00819     to.X = (SHORT)(actx + numchar);
00820     to.Y = from.Top;
00821 
00822     fill.Char.AsciiChar = ' ';
00823     fill.Attributes = wAttributes; // WHICH ATTRIBUTES TO TAKE FOR BLANK CHAR ??
00824 
00825     ScrollConsoleScreenBuffer(hConsole, &from, &clip, to, &fill);
00826 } /* InsertCharacter */
00827 
00828 // Deletes characters under the cursor
00829 // Note that there are cases in which all the following lines should shift by
00830 // a character, but we don't handle these.  This could break some
00831 // VT102-applications, but it shouldn't be too much of an issue.
00832 void TConsole::DeleteCharacter(int numchar)
00833 {
00834     int     actx;
00835     SMALL_RECT  from;
00836     SMALL_RECT  clip;
00837     COORD           to;
00838     CHAR_INFO       fill;
00839 
00840     if ( (actx = GetCursorX()) >= CON_COLS - numchar ) {
00841         ClearEOLine();
00842         return;
00843     } /* IF */
00844 
00845     from.Left =     CON_LEFT + (SHORT)actx;
00846     from.Top =      CON_TOP + (SHORT)GetCursorY();
00847     from.Right =    CON_LEFT + (SHORT)CON_COLS;
00848     from.Bottom =   CON_TOP + from.Top;
00849 
00850     clip = from;
00851     to.X = (SHORT)(actx - numchar);
00852     to.Y = from.Top;
00853 
00854     fill.Char.AsciiChar = ' ';
00855     fill.Attributes = wAttributes; // WHICH ATTRIBUTES TO TAKE FOR BLANK CHAR ??
00856 
00857     ScrollConsoleScreenBuffer(hConsole, &from, &clip, to, &fill);
00858 } /* DeleteCharacter */
00859 
00860 void TConsole::SetRawCursorPosition(int x, int y) {
00861     if (x > CON_WIDTH)  x = CON_WIDTH;
00862     if (x < 0)          x = 0;
00863     if (y > CON_HEIGHT) y = CON_HEIGHT;
00864     if (y < 0)          y = 0;
00865     COORD Coord = {(short)(CON_LEFT + x), (short)(CON_TOP + y)};
00866     SetConsoleCursorPosition(hConsole, Coord);
00867 
00868     // Update the ConsoleInfo struct (Paul Brannan 5/9/98)
00869     ConsoleInfo.dwCursorPosition.Y = Coord.Y;
00870     ConsoleInfo.dwCursorPosition.X = Coord.X;
00871 
00872     // bug fix in case we went too far (Paul Brannan 5/25/98)
00873     if(ConsoleInfo.dwCursorPosition.X < CON_LEFT)
00874         ConsoleInfo.dwCursorPosition.X = CON_LEFT;
00875     if(ConsoleInfo.dwCursorPosition.X > CON_RIGHT)
00876         ConsoleInfo.dwCursorPosition.X = CON_RIGHT;
00877     if(ConsoleInfo.dwCursorPosition.Y < CON_TOP)
00878         ConsoleInfo.dwCursorPosition.Y = CON_TOP;
00879     if(ConsoleInfo.dwCursorPosition.Y > CON_BOTTOM)
00880         ConsoleInfo.dwCursorPosition.Y = CON_BOTTOM;
00881 }
00882 
00883 // The new SetCursorPosition takes scroll regions into consideration
00884 // (Paul Brannan 6/27/98)
00885 void TConsole::SetCursorPosition(int x, int y) {
00886     if (x > CON_WIDTH)  x = CON_WIDTH;
00887     if (x < 0)          x = 0;
00888     if(iScrollEnd != -1) {
00889         if(y > iScrollEnd)      y = iScrollEnd;
00890     } else {
00891         if(y > CON_HEIGHT)      y = CON_HEIGHT;
00892     }
00893     if(iScrollStart != -1) {
00894         if(y < iScrollStart)    y = iScrollStart;
00895     } else {
00896         if(y < 0)               y = 0;
00897     }
00898 
00899     COORD Coord = {(short)(CON_LEFT + x), (short)(CON_TOP + y)};
00900     SetConsoleCursorPosition(hConsole, Coord);
00901 
00902     // Update the ConsoleInfo struct
00903     ConsoleInfo.dwCursorPosition.Y = Coord.Y;
00904     ConsoleInfo.dwCursorPosition.X = Coord.X;
00905 }
00906 
00907 void TConsole::MoveCursorPosition(int x, int y) {
00908     SetCursorPosition(CON_CUR_X + x, CON_CUR_Y + y);
00909 }
00910 
00911 void TConsole::SetExtendedMode(int iFunction, BOOL bEnable)
00912 {
00913     // Probably should do something here...
00914     // Should change the screen mode, but do we need this?
00915 }
00916 
00917 void TConsole::SetScroll(int start, int end) {
00918     iScrollStart = start;
00919     iScrollEnd = end;
00920 }
00921 
00922 void TConsole::Beep() {
00923     if(ini.get_do_beep()) {
00924         if(!ini.get_speaker_beep()) printit("\a");
00925         else ::Beep(400, 100);
00926     }
00927 }
00928 
00929 void TConsole::SetCursorSize(int pct) {
00930     CONSOLE_CURSOR_INFO ci = {(pct != 0)?pct:1, pct != 0};
00931     SetConsoleCursorInfo(hConsole, &ci);
00932 }
00933 
00934 void saveScreen(CHAR_INFO *chiBuffer) {
00935     HANDLE hStdout;
00936     CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
00937     SMALL_RECT srctReadRect;
00938     COORD coordBufSize;
00939     COORD coordBufCoord;
00940 
00941     hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
00942     GetConsoleScreenBufferInfo(hStdout, &ConsoleInfo);
00943 
00944     srctReadRect.Top = CON_TOP;    /* top left: row 0, col 0  */
00945     srctReadRect.Left = CON_LEFT;
00946     srctReadRect.Bottom = CON_BOTTOM; /* bot. right: row 1, col 79 */
00947     srctReadRect.Right = CON_RIGHT;
00948 
00949     coordBufSize.Y = CON_BOTTOM-CON_TOP+1;
00950     coordBufSize.X = CON_RIGHT-CON_LEFT+1;
00951 
00952     coordBufCoord.X = CON_TOP;
00953     coordBufCoord.Y = CON_LEFT;
00954 
00955     ReadConsoleOutput(
00956         hStdout,        /* screen buffer to read from       */
00957         chiBuffer,      /* buffer to copy into              */
00958         coordBufSize,   /* col-row size of chiBuffer        */
00959 
00960         coordBufCoord,  /* top left dest. cell in chiBuffer */
00961         &srctReadRect); /* screen buffer source rectangle   */
00962 }
00963 
00964 void restoreScreen(CHAR_INFO *chiBuffer) {
00965     HANDLE hStdout;
00966     CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
00967     SMALL_RECT srctReadRect;
00968     COORD coordBufSize;
00969     COORD coordBufCoord;
00970 
00971     hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
00972     GetConsoleScreenBufferInfo(hStdout, &ConsoleInfo);
00973 
00974     // restore screen
00975     srctReadRect.Top = CON_TOP;    /* top left: row 0, col 0  */
00976     srctReadRect.Left = CON_LEFT;
00977     srctReadRect.Bottom = CON_BOTTOM; /* bot. right: row 1, col 79 */
00978     srctReadRect.Right = CON_RIGHT;
00979 
00980     coordBufSize.Y = CON_BOTTOM-CON_TOP+1;
00981     coordBufSize.X = CON_RIGHT-CON_LEFT+1;
00982 
00983     coordBufCoord.X = CON_TOP;
00984     coordBufCoord.Y = CON_LEFT;
00985     WriteConsoleOutput(
00986         hStdout, /* screen buffer to write to    */
00987         chiBuffer,        /* buffer to copy from          */
00988         coordBufSize,     /* col-row size of chiBuffer    */
00989         coordBufCoord, /* top left src cell in chiBuffer  */
00990         &srctReadRect); /* dest. screen buffer rectangle */
00991     // end restore screen
00992 
00993 }
00994 
00995 CHAR_INFO* newBuffer() {
00996     CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
00997     HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
00998     GetConsoleScreenBufferInfo(hStdout, &ConsoleInfo);
00999     CHAR_INFO * chiBuffer;
01000     chiBuffer = new CHAR_INFO[(CON_BOTTOM-CON_TOP+1)*(CON_RIGHT-CON_LEFT+1)];
01001     return chiBuffer;
01002 }
01003 
01004 void deleteBuffer(CHAR_INFO* chiBuffer) {
01005     delete[] chiBuffer;
01006 }
01007 

Generated on Sun May 27 2012 04:17:16 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.