Fix bug sometimes causing missing (or spurious) wraparound copy-and-paste

This commit is contained in:
Keith Winstein
2012-04-02 19:04:26 -04:00
parent 7542070b8f
commit 8221838f51
4 changed files with 22 additions and 14 deletions
+2 -2
View File
@@ -57,7 +57,7 @@ void Emulator::print( const Parser::Print *act )
case 1: /* normal character */ case 1: /* normal character */
case 2: /* wide character */ case 2: /* wide character */
if ( fb.ds.auto_wrap_mode && fb.ds.next_print_will_wrap ) { if ( fb.ds.auto_wrap_mode && fb.ds.next_print_will_wrap ) {
fb.get_mutable_row( -1 )->wrap = true; fb.get_mutable_row( -1 )->set_wrap( true );
fb.ds.move_col( 0 ); fb.ds.move_col( 0 );
fb.move_rows_autoscroll( 1 ); fb.move_rows_autoscroll( 1 );
} }
@@ -67,7 +67,7 @@ void Emulator::print( const Parser::Print *act )
&& (chwidth == 2) && (chwidth == 2)
&& (fb.ds.get_cursor_col() == fb.ds.get_width() - 1) ) { && (fb.ds.get_cursor_col() == fb.ds.get_width() - 1) ) {
fb.reset_cell( this_cell ); fb.reset_cell( this_cell );
fb.get_mutable_row( -1 )->wrap = false; fb.get_mutable_row( -1 )->set_wrap( false );
/* There doesn't seem to be a consistent way to get the /* There doesn't seem to be a consistent way to get the
downstream terminal emulator to set the wrap-around downstream terminal emulator to set the wrap-around
copy-and-paste flag on a row that ends with an empty cell copy-and-paste flag on a row that ends with an empty cell
+4 -4
View File
@@ -175,8 +175,8 @@ std::string Display::new_frame( bool initialized, const Framebuffer &last, const
if ( (frame.cursor_x >= f.ds.get_width()) if ( (frame.cursor_x >= f.ds.get_width())
&& (frame.y < f.ds.get_height() - 1) && (frame.y < f.ds.get_height() - 1)
&& f.get_row( frame.y )->wrap && f.get_row( frame.y )->get_wrap()
&& (!initialized || !frame.last_frame.get_row( frame.y )->wrap) ) { && (!initialized || !frame.last_frame.get_row( frame.y )->get_wrap()) ) {
/* next write will wrap */ /* next write will wrap */
frame.cursor_x = 0; frame.cursor_x = 0;
frame.cursor_y++; frame.cursor_y++;
@@ -185,8 +185,8 @@ std::string Display::new_frame( bool initialized, const Framebuffer &last, const
/* Turn off wrap */ /* Turn off wrap */
if ( (frame.y < f.ds.get_height() - 1) if ( (frame.y < f.ds.get_height() - 1)
&& (!f.get_row( frame.y )->wrap) && (!f.get_row( frame.y )->get_wrap())
&& (!initialized || frame.last_frame.get_row( frame.y )->wrap) ) { && (!initialized || frame.last_frame.get_row( frame.y )->get_wrap()) ) {
frame.x = last_x; frame.x = last_x;
if ( initialized ) { if ( initialized ) {
frame.last_frame.reset_cell( frame.last_frame.get_mutable_cell( frame.y, frame.x ) ); frame.last_frame.reset_cell( frame.last_frame.get_mutable_cell( frame.y, frame.x ) );
+3 -1
View File
@@ -30,6 +30,7 @@ void Cell::reset( int background_color )
fallback = false; fallback = false;
width = 1; width = 1;
renditions = Renditions( background_color ); renditions = Renditions( background_color );
wrap = false;
} }
DrawState::DrawState( int s_width, int s_height ) DrawState::DrawState( int s_width, int s_height )
@@ -339,7 +340,8 @@ void Framebuffer::resize( int s_width, int s_height )
for ( std::deque<Row>::iterator i = rows.begin(); for ( std::deque<Row>::iterator i = rows.begin();
i != rows.end(); i != rows.end();
i++ ) { i++ ) {
(*i).cells.resize( s_width, Cell( ds.get_background_rendition() ) ); i->set_wrap( false );
i->cells.resize( s_width, Cell( ds.get_background_rendition() ) );
} }
ds.resize( s_width, s_height ); ds.resize( s_width, s_height );
+13 -7
View File
@@ -57,19 +57,22 @@ namespace Terminal {
char fallback; /* first character is combining character */ char fallback; /* first character is combining character */
int width; int width;
Renditions renditions; Renditions renditions;
bool wrap; /* if last cell, wrap to next line */
Cell( int background_color ) Cell( int background_color )
: contents(), : contents(),
fallback( false ), fallback( false ),
width( 1 ), width( 1 ),
renditions( background_color ) renditions( background_color ),
wrap( false )
{} {}
Cell() /* default constructor required by C++11 STL */ Cell() /* default constructor required by C++11 STL */
: contents(), : contents(),
fallback( false ), fallback( false ),
width( 1 ), width( 1 ),
renditions( 0 ) renditions( 0 ),
wrap( false )
{ {
assert( false ); assert( false );
} }
@@ -81,7 +84,8 @@ namespace Terminal {
return ( (contents == x.contents) return ( (contents == x.contents)
&& (fallback == x.fallback) && (fallback == x.fallback)
&& (width == x.width) && (width == x.width)
&& (renditions == x.renditions) ); && (renditions == x.renditions)
&& (wrap == x.wrap) );
} }
wchar_t debug_contents( void ) const; wchar_t debug_contents( void ) const;
@@ -97,14 +101,13 @@ namespace Terminal {
class Row { class Row {
public: public:
std::vector<Cell> cells; std::vector<Cell> cells;
bool wrap;
Row( size_t s_width, int background_color ) Row( size_t s_width, int background_color )
: cells( s_width, Cell( background_color ) ), wrap( false ) : cells( s_width, Cell( background_color ) )
{} {}
Row() /* default constructor required by C++11 STL */ Row() /* default constructor required by C++11 STL */
: cells( 1, Cell() ), wrap( false ) : cells( 1, Cell() )
{ {
assert( false ); assert( false );
} }
@@ -116,8 +119,11 @@ namespace Terminal {
bool operator==( const Row &x ) const bool operator==( const Row &x ) const
{ {
return ( (cells == x.cells) && (wrap == x.wrap) ); return ( cells == x.cells );
} }
bool get_wrap( void ) const { return cells.back().wrap; }
void set_wrap( bool w ) { cells.back().wrap = w; }
}; };
class SavedCursor { class SavedCursor {