From 39dfccf4504219576389256599dadd2a0189346a Mon Sep 17 00:00:00 2001 From: Keith Winstein Date: Tue, 1 Feb 2011 02:11:46 -0500 Subject: [PATCH] Support insert mode and erase character --- terminal.cpp | 6 ++++++ terminalframebuffer.cpp | 3 ++- terminalframebuffer.hpp | 1 + terminalfunctions.cpp | 47 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/terminal.cpp b/terminal.cpp index e55948c..f5d6821 100644 --- a/terminal.cpp +++ b/terminal.cpp @@ -68,6 +68,12 @@ void Emulator::print( Parser::Print *act ) fb.move_rows_autoscroll( 1 ); } + if ( fb.ds.insert_mode ) { + for ( int i = 0; i < chwidth; i++ ) { + fb.insert_cell( fb.ds.get_cursor_row(), fb.ds.get_cursor_col() ); + } + } + this_cell = fb.get_cell(); this_cell->reset(); diff --git a/terminalframebuffer.cpp b/terminalframebuffer.cpp index 3af159e..40c7f27 100644 --- a/terminalframebuffer.cpp +++ b/terminalframebuffer.cpp @@ -46,7 +46,8 @@ DrawState::DrawState( int s_width, int s_height ) combining_char_col( 0 ), combining_char_row( 0 ), tabs( s_width ), scrolling_region_top_row( 0 ), scrolling_region_bottom_row( height - 1 ), renditions(), save(), - next_print_will_wrap( false ), origin_mode( false ), auto_wrap_mode( true ) + next_print_will_wrap( false ), origin_mode( false ), auto_wrap_mode( true ), + insert_mode( false ) { for ( int i = 0; i < width; i++ ) { tabs[ i ] = ( (i % 8) == 0 ); diff --git a/terminalframebuffer.hpp b/terminalframebuffer.hpp index a5072e8..970091a 100644 --- a/terminalframebuffer.hpp +++ b/terminalframebuffer.hpp @@ -66,6 +66,7 @@ namespace Terminal { bool next_print_will_wrap; bool origin_mode; bool auto_wrap_mode; + bool insert_mode; /* bold, etc. */ diff --git a/terminalfunctions.cpp b/terminalfunctions.cpp index f50e0a9..c5682fb 100644 --- a/terminalfunctions.cpp +++ b/terminalfunctions.cpp @@ -249,6 +249,39 @@ void CSI_DECRM( Framebuffer *fb, Dispatcher *dispatch ) static Function func_CSI_DECSM( CSI, "?h", CSI_DECSM ); static Function func_CSI_DECRM( CSI, "?l", CSI_DECRM ); +static bool *get_ANSI_mode( int param, Framebuffer *fb ) { + switch ( param ) { + case 4: /* insert/replace mode */ + return &(fb->ds.insert_mode); + } + return NULL; +} + +/* set mode */ +void CSI_SM( Framebuffer *fb, Dispatcher *dispatch ) +{ + for ( int i = 0; i < dispatch->param_count(); i++ ) { + bool *mode = get_ANSI_mode( dispatch->getparam( i, 0 ), fb ); + if ( mode ) { + *mode = true; + } + } +} + +/* clear mode */ +void CSI_RM( Framebuffer *fb, Dispatcher *dispatch ) +{ + for ( int i = 0; i < dispatch->param_count(); i++ ) { + bool *mode = get_ANSI_mode( dispatch->getparam( i, 0 ), fb ); + if ( mode ) { + *mode = false; + } + } +} + +static Function func_CSI_SM( CSI, "h", CSI_SM ); +static Function func_CSI_RM( CSI, "l", CSI_RM ); + /* set top and bottom margins */ void CSI_DECSTBM( Framebuffer *fb, Dispatcher *dispatch ) { @@ -392,3 +425,17 @@ void CSI_HPA( Framebuffer *fb, Dispatcher *dispatch ) static Function func_CSI_CHA( CSI, "G", CSI_HPA ); /* ECMA-48 name: CHA */ static Function func_CSI_HPA( CSI, "\x60", CSI_HPA ); /* ECMA-48 name: HPA */ + +/* erase character */ +void CSI_ECH( Framebuffer *fb, Dispatcher *dispatch ) +{ + int num = dispatch->getparam( 0, 1 ); + int limit = fb->ds.get_cursor_col() + num; + if ( limit >= fb->ds.get_width() ) { + limit = fb->ds.get_width() - 1; + } + + clearline( fb, -1, fb->ds.get_cursor_col(), limit ); +} + +static Function func_CSI_ECH( CSI, "X", CSI_ECH );