/* $Id: TERMINAL.CPP 2.4 1995/07/20 11:24:33 leon Exp $
*
* GISEL - G-CODE ISEL CNC driver
*
* Copyright (c) 1994 LECAD
* All Rights Reserved.
*
*/
#define Uses_TKeys
#define Uses_TRect
#define Uses_TEvent
#define Uses_TButton
#define Uses_TDialog
#define Uses_TMenuBar
#define Uses_TSubMenu
#define Uses_TMenuItem
#define Uses_TStaticText
#define Uses_TStreamableClass
#define Uses_TStreamable
#define Uses_TDeskTop
#define Uses_MsgBox
#define Uses_TApplication
#define Uses_TScroller
#define Uses_TTerminal
#include <tvision/tv.h>
__link( RView )
__link( RWindow )
__link(RScroller)
__link(RScrollBar)
#include <iostream.h>
#include <fstream.h>
#include <strstrea.h>
#include <string.h>
#include <ctype.h>
#pragma hdrstop
#include <conio.h>
#include <ctype.h>
#include <stdio.h> // sprintf()
#include "gisel.h"
#include "config.h"
#include "gadgets.h"
#include "terminal.h"
#include "comm.h"
/** Global Settings **/
extern SettingsRec *Settings;
const char * const TTermWindow::name = "TTermWindow";
#define INTRO "ISEL C-Series Terminal...\n"
#define NOCOM "Error: Terminal port is not available\n\n"
/**
** TTermWindow constructor
**/
TTermWindow::TTermWindow(const TRect& bounds, const char *aTitle,
short aNumber) :
TWindow( bounds, aTitle, aNumber ),
TWindowInit( initFrame )
{
TRect r( getExtent() );
r.grow(-1, -1);
options |= ofTileable;
TTermView *t = new TTermView( r,
standardScrollBar(sbHorizontal | sbHandleKeyboard),
standardScrollBar(sbVertical | sbHandleKeyboard)
);
if( t != 0 )
insert(t);
else
messageBox("Cannot enter terminal mode.", mfOKButton);
}
/** Reads window from the stream
**/
void *TTermWindow::read(ipstream& is)
{
TWindow::read(is);
TRect r( getExtent() );
r.grow(-1, -1);
//options |= ofTileable;
#if 0
TTermView *t = new TTermView( r,
standardScrr(sbHorizontal | sbHandleKeyboard ),
standardScrollBar(sbVertical | sbHandleKeyboard )
);
if( t != 0 )
insert(t);
else
messageBox("Cannot enter terminal mode.", mfOKButton);
#endif
return this;
}
/** {duh} **/
void TTermWindow::write(opstream& os)
{
TWindow::write(os);
}
/** {duh} **/
TStreamable *TTermWindow::build()
{
return new TTermWindow( streamableInit );
}
TStreamableClass RTermWindow( TTermWindow::name,
TTermWindow::build,
__DELTA(TTermWindow)
);
/**
** Constructor for terminal view
**/
TTermView::TTermView( const TRect& bounds,
TScrollBar *aHScrollBar,
TScrollBar *aVScrollBar
) :
TTerminal( bounds, aHScrollBar, aVScrollBar, 8192U )
{
do_sputn( INTRO, strlen(INTRO) );
char buffer[10];
sprintf(buffer, "\n%s%ld", PROMPT, Settings->device);
prompt = strdup(buffer);
do_sputn( prompt, strlen(prompt) );
}
/**
** Terminal destructor
**/
TTermView::~TTermView()
{
delete prompt;
}
/**
** Hanbdles terminal events
**/
void TTermView::handleEvent( TEvent& event )
{
TTerminal::handleEvent( event );
ushort keyCode = event.keyDown.keyCode ;
if( event.what == evKeyboard &&
event.keyDown.charScan.charCode != 0 &&
isascii( event.keyDown.charScan.charCode )
)
{
if (keyCode == kbEnter) // Send whole line at ENTER
{
if (comm->getReply() < 0)
messageBox("You must wait for the acknowledge signal from the "
"controller before transmitting any additional information.",
mfOKButton | mfWarning);
ushort start = prevLines(queFront, 1);
// BUG: No buffer wrap checking
comm->sendCommand(&buffer[start], queFront - start);
do_sputn(prompt, strlen(prompt));
}
else
do_sputc( keyCode );
drawView();
clearEvent( event );
}
}
/**
** Draws terminal window
**/
void TTermView::draw()
{
short i;
ushort begLine, endLine;
char s[256];
ushort 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);
memcpy( s, &buffer[begLine], T );
s[T] = EOS;
}
else
{
int T = (int) (bufSize - begLine);
memcpy( s, &buffer[begLine], T );
memcpy( s+T, buffer, endLine );
s[T+endLine] = EOS;
}
if( delta.x >= 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 );
}
}
/**
** Inserts charcter into thw terminal window
**/
void TTermView::do_sputc( const char c )
{
ushort screenLines = limit.y;
int i;
if( c == '\n' )
screenLines++;
if( !canInsert( 1 ) )
{
queBack = nextLine( queBack );
screenLines--;
}
if( c != '\x08' )
{
buffer[queFront++] = c;
if( queFront == bufSize )
queFront = 0;
}
else if( queFront != queBack )
{
--queFront;
if( (int) queFront < 0 )
queFront += bufSize;
if( buffer[queFront] == '\n' )
--screenLines;
}
++drawLock;
setLimit( limit.x, screenLines );
scrollTo( 0, screenLines + 1 );
--drawLock;
i = prevLines( queFront, 1 );
if( i <= queFront )
i = queFront - i;
else
i = bufSize - (i - queFront);
setCursor( i, screenLines - delta.y - 1 );
return;
}
/**
** Inserts /count/ character into the terminal window
**/
int TTermView::do_sputn( const char *s, int count )
{
ushort screenLines = limit.y;
for( ushort i = 0; i < count; i++ )
if( s[i] == '\n' )
screenLines++;
while( !canInsert( count ) ) // purge last line(s) to make room
{
queBack = nextLine( queBack );
screenLines--;
}
if( queFront + count >= bufSize ) // wrap around cyclic buffer
{
i = bufSize - queFront;
memcpy( &buffer[queFront], s, i );
memcpy( buffer, &s[i], count - i );
queFront = count - i;
}
else // normal insert
{
memcpy( &buffer[queFront], s, count );
queFront += count;
}
++drawLock;
setLimit( limit.x, screenLines );
scrollTo( 0, screenLines + 1 );
--drawLock;
i = prevLines( queFront, 1 );
if( i <= queFront )
i = queFront - i;
else
i = bufSize - (i - queFront);
setCursor( i, screenLines - delta.y - 1 );
return count;
}
syntax highlighted by Code2HTML, v. 0.9.1