/* * Turbo Vision - Version 2.0 * * Copyright (c) 1994 by Borland International * All Rights Reserved. * Modified by Robert H”hne to be used for RHIDE. Modified to compile with gcc v3.x by Salvador E. Tropea, with the help of Andris Pavenis. * * */ // SET: Moved the standard headers here because according to DJ // they can inconditionally declare symbols like NULL #include // The SSC code doesn't support as much as needed for it. #ifndef HAVE_SSC #define Uses_string #define Uses_TTextDevice #define Uses_TTerminal #define Uses_otstream #include UsingNamespaceStd TTerminal::TTerminal( const TRect& bounds, TScrollBar *aHScrollBar, TScrollBar *aVScrollBar, uint32 aBufSize ) : TTextDevice(bounds, aHScrollBar, aVScrollBar), queFront( 0 ), queBack( 0 ) { growMode = gfGrowHiX + gfGrowHiY; bufSize = aBufSize; buffer = new char[ bufSize ]; setLimit( 0, 1 ); setCursor( 0, 0 ); showCursor(); } TTerminal::~TTerminal() { delete buffer; } Boolean TTerminal::canInsert( uint32 amount ) { int32 T = (queFront < queBack) ? ( queFront + amount ) : ( int32(queFront) - bufSize + amount); // cast needed so we get // signed comparison return Boolean( (int32)queBack > T ); } const int MaxLineLen=256; void TTerminal::draw() { short i; uint32 begLine, endLine; char s[MaxLineLen]; int32 bottomLine; bottomLine = size.y + delta.y; if( limit.y > bottomLine ) { endLine = prevLines( queFront, limit.y - bottomLine ); bufDec( endLine ); } else endLine = queFront; if( limit.y > size.y ) i = size.y - 1; else { for( i = limit.y; i <= size.y - 1; i++ ) writeChar(0, i, ' ', 1, size.x); i = limit.y - 1; } for( ; i >= 0; i-- ) { begLine = prevLines(endLine, 1); if (endLine >= begLine) { int T = int( endLine - begLine ); if (T>=MaxLineLen) T=MaxLineLen-1; memcpy( s, &buffer[begLine], T ); s[T] = EOS; } else { int T=int( bufSize - begLine); if (T>=MaxLineLen) T=MaxLineLen-1; memcpy( s, &buffer[begLine], T ); int T2=endLine; if (T+T2>=MaxLineLen) T2=MaxLineLen-T-1; memcpy( s+T, buffer, T2 ); s[T+T2] = EOS; } if( delta.x >= (int32)strlen(s) ) *s = EOS; else strcpy( s, &s[delta.x] ); writeStr( 0, i, s, 1 ); writeChar( strlen(s), i, ' ', 1, size.x ); endLine = begLine; bufDec( endLine ); } } uint32 TTerminal::nextLine( uint32 pos ) { if( pos != queFront ) { while( buffer[pos] != '\n' && pos != queFront ) bufInc(pos); if( pos != queFront ) bufInc( pos ); } return pos; } int TTerminal::do_sputn( const char *s, int count ) { ushort screenLines = limit.y; int32 i; for( i = 0; i < count; i++ ) if( s[i] == '\n' ) screenLines++; while( !canInsert( count ) ) { queBack = nextLine( queBack ); screenLines--; } if( queFront + count >= bufSize ) { i = bufSize - queFront; memcpy( &buffer[queFront], s, i ); memcpy( buffer, &s[i], count - i ); queFront = count - i; } else { memcpy( &buffer[queFront], s, count ); queFront += count; } setLimit( limit.x, screenLines ); scrollTo( 0, screenLines + 1 ); i = prevLines( queFront, 1 ); if( i <= (int32)queFront ) i = queFront - i; else i = bufSize - (i - queFront); setCursor( i, screenLines - delta.y - 1 ); drawView(); return count; } Boolean TTerminal::queEmpty() { return Boolean( queBack == queFront ); } otstream::otstream( TTerminal *tt ) #ifdef CLY_ISOCpp98 // SET: Andris used it. It looks like the new standard doesn't have a // default constructor : std::ostream (tt) #endif { ios::init( tt ); } // SET: It was really broken, but as we never used it... // I rewrote it. I also used bufInc and bufDec and made it inline. (instead // of the old macros). uint32 TTerminal::prevLines(uint32 posStart, uint32 Lines) { uint32 pos=posStart; // If that's the start just return, we can't go back. Remmember that's a // circular buffer. if (!Lines || pos==queBack) return pos; // go back 1 character, is to skip the EOL bufDec(pos); if (pos=queBack); return queBack; } #endif