⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ansiterm.cpp

📁 DOS下采用中断接收数据的串口通讯的例子,很难找到的好东西!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
              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 + -