📄 ansiterm.cpp
字号:
return 1;
}
break;
}
}
}
// This routine is the high level controller for the terminal
// emulation class. It calls parse_ansi_string() to break the
// escape sequence down into usable components, then dispatches
// the appropriate member function to do the work. If DEBUG is
// switched on, the escape sequence is dumped out to the debug
// window.
void AnsiTerminal::parse( void )
{
if ( parse_ansi_string() ) {
#if defined( DEBUG )
debug_window->Goto();
DisplayAttribute att = debug_window->GetAttribute();
debug_window->SetAttribute( att ^ 0x77 );
*debug_window << "ESC [ ";
for ( int i = 0 ; i <= parm_count; i++ )
*debug_window << "<" << ansi_parms[ i ] << ">";
*debug_window << " ";
window->Goto();
#endif
switch( ansi_parms[ parm_count ][ 0 ] ) {
case 'A' : cursor_move( -1, 0 ); break;
case 'B' : cursor_move( 1, 0 ); break;
case 'C' : cursor_move( 0, 1 ); break;
case 'D' : cursor_move( 0, -1 ); break;
case 'H' : position_cursor(); break;
case 'J' : erase_in_display(); break;
case 'K' : erase_in_line(); break;
case 'f' : position_cursor(); break;
case 'l' : set_mode(); break;
case 'h' : set_mode(); break;
case 'm' : set_color(); break;
case 'n' : cursor_position_report(); break;
case 's' : save_position(); break;
case 'u' : restore_position(); break;
}
}
}
// ESC[#;#f and ESC[#;#H
//
// These two commands have the same effect, which is to position
// the cursor at a location specified by the two numbers, which
// are a row and column sequence. One or both parameters can be
// omitted, in which case the default value of 1 is used. Note
// that row and column numbers in ANSI are 1 based, while the
// BaseWindow class numbers are 0 based.
void AnsiTerminal::position_cursor()
{
int row;
int col;
if ( parm_count > 0 )
row = atoi( ansi_parms[ 0 ] );
else
row = 1;
if ( parm_count > 1 )
col = atoi( ansi_parms[ 1 ] );
else
col = 1;
window->SetPosition( row - 1, col - 1 );
}
// ESC[#A Cursor up
// ESC[#B Cursor down
// ESC[#C Cursor right
// ESC[#D Cursor left
//
// These four commands are all handled with this member function.
// The single numeric parameter defaults to 1 if it is omitted.
// Any movement outside the screen bounds is ignored by the
// BaseWindow functions, so this routine doesn't have to worry
// about it.
void AnsiTerminal::cursor_move( int row_dir, int col_dir )
{
int offset;
int row;
int col;
if ( parm_count > 0 )
offset = atoi( ansi_parms[ 0 ] );
else
offset = 1;
window->GetPosition( row, col );
row += offset * row_dir;
col += offset * col_dir;
window->SetPosition( row, col );
}
// ESC[6n Device Status Report
//
// This command is handled by issuing a Cursor Position Report
// sequence, ESC[#;#R, with the two numeric parameters being the
// row and column number. Note that handling the command this way
// is somewhat idiosynchratic to the PC.
void AnsiTerminal::cursor_position_report( void )
{
int row;
int col;
char temp[ 40 ];
if ( parm_count != 1 )
return;
if ( strcmp( ansi_parms[ 0 ], "6" ) != 0 )
return;
window->GetPosition( row, col );
sprintf( temp, "%c[%d;%dR", ESC, row + 1, col + 1 );
port->Write( temp );
}
// ESC[2J Erase in display
//
// The official ANSI version of this command will erase some or
// all of the display, depending on the value of the numeric
// parameters. The IBM PC version only support parameter 2, which
// erases the entire display. The cursor is homed as part of this
// command.
void AnsiTerminal::erase_in_display( void )
{
if ( parm_count != 1 )
return;
if ( strcmp( ansi_parms[ 0 ], "2" ) != 0 )
return;
window->Clear();
window->SetPosition( 0, 0 );
}
// ESC[K Erase in line
//
// This is another ANSI command that is only partially supported
// by IBM ANSI. When no numeric parameter is given, the line is
// erased from the cursor position to the end of the line.
void AnsiTerminal::erase_in_line( void )
{
int row;
int col;
int width;
int height;
int i;
if ( parm_count != 0 )
return;
window->GetPosition( row, col );
window->GetDimensions( width, height );
for ( i = col ; i < width; i++ )
*window << ' ';
window->SetPosition( row, col );
}
// ESC[s Save Cursor Position
//
// This command saves off the current cursor position for later
// restoration. This is an IBM extension to the ANSI standard.
void AnsiTerminal::save_position( void )
{
if ( parm_count != 0 )
return;
window->GetPosition( saved_row, saved_col );
}
// ESC[u Restore Cursor Position
//
// Another IBM extension to the ANSI standard. This command
// restores the previously saved cursor position.
void AnsiTerminal::restore_position( void )
{
if ( parm_count != 0 )
return;
window->SetPosition( saved_row, saved_col );
}
// ESC[#;#;...;#m Set Graphics Rendition
//
// This command sets the current display attributes to various
// attributes. Multiple command parameters can be strung
// together in unlimited combinations. This implementation is
// limited to 14 parameters.
void AnsiTerminal::set_color( void )
{
int command;
int att;
for ( int i = 0 ; i < parm_count ; i++ ) {
command = atoi( ansi_parms[ i ] );
att = window->GetAttribute();
switch( command ) {
case 0 : att = NORMAL_ATTRIBUTE; break;
case 1 : att = att | 8; break;
case 5 : att = att | 0x80; break;
case 7 : att = REVERSE_ATTRIBUTE; break;
case 8 : att = INVISIBLE_ATTRIBUTE; break;
case 30 : att = ( att & 0xf0 ) | 0x00; break;
case 31 : att = ( att & 0xf0 ) | 0x04; break;
case 32 : att = ( att & 0xf0 ) | 0x02; break;
case 33 : att = ( att & 0xf0 ) | 0x0e; break;
case 34 : att = ( att & 0xf0 ) | 0x01; break;
case 35 : att = ( att & 0xf0 ) | 0x05; break;
case 36 : att = ( att & 0xf0 ) | 0x03; break;
case 37 : att = ( att & 0xf0 ) | 0x07; break;
case 40 : att = ( att & 0x0f ) | 0x00; break;
case 41 : att = ( att & 0x0f ) | 0x40; break;
case 42 : att = ( att & 0x0f ) | 0x20; break;
case 43 : att = ( att & 0x0f ) | 0x60; break;
case 44 : att = ( att & 0x0f ) | 0x10; break;
case 45 : att = ( att & 0x0f ) | 0x50; break;
case 46 : att = ( att & 0x0f ) | 0x30; break;
case 47 : att = ( att & 0x0f ) | 0x70; break;
}
window->SetAttribute( att );
}
}
// ESC[=#h ESC[=#l Set/Reset Mode
// ESC[=h ESC[=l
// ESC[=0h ESC[=0l
// ESC[?7h ESC[?7l
//
// This command is used to change the current video mode. The
// TextWindow class used here doesn't support changing modes, so
// most versions of this command aren't supported.d The single
// exception is the last version, which turns on/off line wrap.
void AnsiTerminal::set_mode( void )
{
if ( parm_count != 2 )
return;
if ( strcmp( ansi_parms[ 0 ], "?" ) != 0 &&
strcmp( ansi_parms[ 0 ], "=" ) != 0 )
return;
if ( strcmp( ansi_parms[ 1 ], "7" ) != 0 )
return;
switch( ansi_parms[ 2 ][ 0 ] ) {
case 'h' : window->SetWrap( 1 ); break;
case 'l' : window->SetWrap( 0 ); break;
}
}
// Writing a key to the serial port is done by checking to see if
// a translation is defined. If not, the key itself is sent out,
// otherwise the translation is sent.
void AnsiTerminal::WriteKey( int key )
{
char *translation;
if ( extended_keys && key > 256 ) {
translation = extended_keys[ ( key >> 8 ) & 0xff ];
if ( translation != 0 )
port->Write( translation );
} else {
if ( keys )
translation = keys[ key & 0xff ];
else
translation = 0;
if ( translation != 0 )
port->Write( translation );
else
port->Write( key );
}
}
// ******************* END OF ANSITERM.CPP *******************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -