Refactor display to be outside of terminal and add some const correctness

This commit is contained in:
Keith Winstein
2011-08-13 15:06:37 -04:00
parent 945acbca37
commit 023eb182d0
9 changed files with 123 additions and 106 deletions
+3 -1
View File
@@ -70,9 +70,11 @@ void UserByte::act_on_terminal( Terminal::Emulator *emu )
{ {
emu->dispatch.terminal_to_host.append( emu->user.input( this, emu->dispatch.terminal_to_host.append( emu->user.input( this,
emu->fb.ds.application_mode_cursor_keys ) ); emu->fb.ds.application_mode_cursor_keys ) );
if ( c == 0x0c ) { /* Ctrl-L */ /*
if ( c == 0x0c ) { // Ctrl-L
emu->display.invalidate(); emu->display.invalidate();
} }
*/
} }
void Resize::act_on_terminal( Terminal::Emulator *emu ) void Resize::act_on_terminal( Terminal::Emulator *emu )
+9 -3
View File
@@ -122,7 +122,7 @@ int main( void )
} }
/* Print a frame if the last frame was more than 1/50 seconds ago */ /* Print a frame if the last frame was more than 1/50 seconds ago */
bool tick( Terminal::Emulator *e ) bool tick( Terminal::Emulator *e, Terminal::Display *d, Terminal::Framebuffer &state )
{ {
static bool initialized = false; static bool initialized = false;
static struct timeval last_time; static struct timeval last_time;
@@ -138,8 +138,10 @@ bool tick( Terminal::Emulator *e )
if ( (!initialized) if ( (!initialized)
|| (diff >= 0.02) ) { || (diff >= 0.02) ) {
std::string update = e->new_frame(); std::string update = d->new_frame( initialized, state, e->get_fb() );
swrite( STDOUT_FILENO, update.c_str() ); swrite( STDOUT_FILENO, update.c_str() );
state = e->get_fb();
initialized = true; initialized = true;
last_time = this_time; last_time = this_time;
@@ -198,6 +200,8 @@ void emulate_terminal( int fd )
/* open parser and terminal */ /* open parser and terminal */
Parser::UTF8Parser parser; Parser::UTF8Parser parser;
Terminal::Emulator terminal( window_size.ws_col, window_size.ws_row ); Terminal::Emulator terminal( window_size.ws_col, window_size.ws_row );
Terminal::Display display;
Terminal::Framebuffer state( window_size.ws_col, window_size.ws_row );
struct pollfd pollfds[ 3 ]; struct pollfd pollfds[ 3 ];
@@ -255,15 +259,17 @@ void emulate_terminal( int fd )
break; break;
} }
if ( tick( &terminal ) ) { /* there was a frame */ if ( tick( &terminal, &display, state ) ) { /* there was a frame */
poll_timeout = -1; poll_timeout = -1;
} else { } else {
poll_timeout = 20; poll_timeout = 20;
} }
} }
/* XXX last frame
std::string update = terminal.new_frame(); std::string update = terminal.new_frame();
swrite( STDOUT_FILENO, update.c_str() ); swrite( STDOUT_FILENO, update.c_str() );
*/
swrite( STDOUT_FILENO, terminal.close().c_str() ); swrite( STDOUT_FILENO, terminal.close().c_str() );
} }
+6 -6
View File
@@ -10,7 +10,7 @@
using namespace Terminal; using namespace Terminal;
Emulator::Emulator( size_t s_width, size_t s_height ) Emulator::Emulator( size_t s_width, size_t s_height )
: fb( s_width, s_height ), dispatch(), user(), display( s_width, s_height ) : fb( s_width, s_height ), dispatch(), user()
{} {}
std::string Emulator::read_octets_to_host( void ) std::string Emulator::read_octets_to_host( void )
@@ -32,7 +32,7 @@ void Emulator::print( Parser::Print *act )
int chwidth = act->ch == L'\0' ? -1 : wcwidth( act->ch ); int chwidth = act->ch == L'\0' ? -1 : wcwidth( act->ch );
Cell *this_cell = fb.get_cell(); Cell *this_cell = fb.get_mutable_cell();
Cell *combining_cell = fb.get_combining_cell(); /* can be null if we were resized */ Cell *combining_cell = fb.get_combining_cell(); /* can be null if we were resized */
@@ -40,7 +40,7 @@ void Emulator::print( 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_row( -1 )->wrap = true; fb.get_mutable_row( -1 )->wrap = true;
fb.ds.move_col( 0 ); fb.ds.move_col( 0 );
fb.move_rows_autoscroll( 1 ); fb.move_rows_autoscroll( 1 );
} }
@@ -50,7 +50,7 @@ void Emulator::print( 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_row( -1 )->wrap = false; fb.get_mutable_row( -1 )->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
@@ -65,7 +65,7 @@ void Emulator::print( Parser::Print *act )
} }
} }
this_cell = fb.get_cell(); this_cell = fb.get_mutable_cell();
fb.reset_cell( this_cell ); fb.reset_cell( this_cell );
this_cell->contents.push_back( act->ch ); this_cell->contents.push_back( act->ch );
@@ -74,7 +74,7 @@ void Emulator::print( Parser::Print *act )
if ( chwidth == 2 ) { /* erase overlapped cell */ if ( chwidth == 2 ) { /* erase overlapped cell */
if ( fb.ds.get_cursor_col() + 1 < fb.ds.get_width() ) { if ( fb.ds.get_cursor_col() + 1 < fb.ds.get_width() ) {
fb.reset_cell( fb.get_cell( fb.ds.get_cursor_row(), fb.ds.get_cursor_col() + 1 ) ); fb.reset_cell( fb.get_mutable_cell( fb.ds.get_cursor_row(), fb.ds.get_cursor_col() + 1 ) );
} }
} }
+1 -2
View File
@@ -32,7 +32,6 @@ namespace Terminal {
Framebuffer fb; Framebuffer fb;
Dispatcher dispatch; Dispatcher dispatch;
UserInput user; UserInput user;
Display display;
/* action methods */ /* action methods */
void print( Parser::Print *act ); void print( Parser::Print *act );
@@ -50,7 +49,7 @@ namespace Terminal {
std::string open( void ); /* put user cursor keys in application mode */ std::string open( void ); /* put user cursor keys in application mode */
std::string close( void ); /* restore user cursor keys */ std::string close( void ); /* restore user cursor keys */
std::string new_frame( void ) { return display.new_frame( fb ); } const Framebuffer & get_fb( void ) { return fb; }
}; };
} }
+52 -44
View File
@@ -6,15 +6,15 @@ using namespace Terminal;
/* Print a new "frame" to the terminal, using ANSI/ECMA-48 escape codes. */ /* Print a new "frame" to the terminal, using ANSI/ECMA-48 escape codes. */
std::string Display::new_frame( Framebuffer &f ) std::string Display::new_frame( bool initialized, const Framebuffer &last, const Framebuffer &f )
{ {
FrameState frame; FrameState frame( last );
char tmp[ 64 ]; char tmp[ 64 ];
/* has window title changed? */ /* has window title changed? */
if ( (!initialized) if ( (!initialized)
|| (f.get_window_title() != last_frame.get_window_title()) ) { || (f.get_window_title() != frame.last_frame.get_window_title()) ) {
/* set window title */ /* set window title */
frame.append( "\033]0;[stm] " ); frame.append( "\033]0;[stm] " );
std::vector<wchar_t> window_title = f.get_window_title(); std::vector<wchar_t> window_title = f.get_window_title();
@@ -29,7 +29,7 @@ std::string Display::new_frame( Framebuffer &f )
/* has reverse video state changed? */ /* has reverse video state changed? */
if ( (!initialized) if ( (!initialized)
|| (f.ds.reverse_video != last_frame.ds.reverse_video) ) { || (f.ds.reverse_video != frame.last_frame.ds.reverse_video) ) {
/* set reverse video */ /* set reverse video */
snprintf( tmp, 64, "\033[?5%c", (f.ds.reverse_video ? 'h' : 'l') ); snprintf( tmp, 64, "\033[?5%c", (f.ds.reverse_video ? 'h' : 'l') );
frame.append( tmp ); frame.append( tmp );
@@ -37,13 +37,17 @@ std::string Display::new_frame( Framebuffer &f )
/* has size changed? */ /* has size changed? */
if ( (!initialized) if ( (!initialized)
|| (f.ds.get_width() != last_frame.ds.get_width()) || (f.ds.get_width() != frame.last_frame.ds.get_width())
|| (f.ds.get_height() != last_frame.ds.get_height()) ) { || (f.ds.get_height() != frame.last_frame.ds.get_height()) ) {
/* clear screen */ /* clear screen */
frame.append( "\033[0m\033[H\033[2J" ); frame.append( "\033[0m\033[H\033[2J" );
initialized = false; initialized = false;
cursor_x = cursor_y = 0; frame.cursor_x = frame.cursor_y = 0;
current_rendition_string = "\033[0m"; frame.current_rendition_string = "\033[0m";
} else {
frame.cursor_x = frame.last_frame.ds.get_cursor_col();
frame.cursor_y = frame.last_frame.ds.get_cursor_row();
frame.current_rendition_string = frame.last_frame.ds.get_renditions().sgr();
} }
/* shortcut -- has display moved up by a certain number of lines? */ /* shortcut -- has display moved up by a certain number of lines? */
@@ -54,7 +58,7 @@ std::string Display::new_frame( Framebuffer &f )
int scroll_height = 0; int scroll_height = 0;
for ( int row = 0; row < f.ds.get_height(); row++ ) { for ( int row = 0; row < f.ds.get_height(); row++ ) {
if ( *(f.get_row( 0 )) == *(last_frame.get_row( row )) ) { if ( *(f.get_row( 0 )) == *(frame.last_frame.get_row( row )) ) {
/* found a scroll */ /* found a scroll */
lines_scrolled = row; lines_scrolled = row;
scroll_height = 1; scroll_height = 1;
@@ -64,7 +68,7 @@ std::string Display::new_frame( Framebuffer &f )
lines_scrolled + region_height < f.ds.get_height(); lines_scrolled + region_height < f.ds.get_height();
region_height++ ) { region_height++ ) {
if ( *(f.get_row( region_height )) if ( *(f.get_row( region_height ))
== *(last_frame.get_row( lines_scrolled + region_height )) ) { == *(frame.last_frame.get_row( lines_scrolled + region_height )) ) {
scroll_height = region_height + 1; scroll_height = region_height + 1;
} else { } else {
break; break;
@@ -79,17 +83,17 @@ std::string Display::new_frame( Framebuffer &f )
frame.y = scroll_height; frame.y = scroll_height;
if ( lines_scrolled ) { if ( lines_scrolled ) {
if ( cursor_y != f.ds.get_height() - 1 ) { if ( frame.cursor_y != f.ds.get_height() - 1 ) {
snprintf( tmp, 64, "\033[%d;%dH", f.ds.get_height(), 1 ); snprintf( tmp, 64, "\033[%d;%dH", f.ds.get_height(), 1 );
frame.append( tmp ); frame.append( tmp );
cursor_y = f.ds.get_height() - 1; frame.cursor_y = f.ds.get_height() - 1;
cursor_x = 0; frame.cursor_x = 0;
} }
if ( current_rendition_string != "\033[0m" ) { if ( frame.current_rendition_string != "\033[0m" ) {
frame.append( "\033[0m" ); frame.append( "\033[0m" );
current_rendition_string = "\033[0m"; frame.current_rendition_string = "\033[0m";
} }
for ( int i = 0; i < lines_scrolled; i++ ) { for ( int i = 0; i < lines_scrolled; i++ ) {
@@ -98,9 +102,9 @@ std::string Display::new_frame( Framebuffer &f )
for ( int i = 0; i < f.ds.get_height(); i++ ) { for ( int i = 0; i < f.ds.get_height(); i++ ) {
if ( i + lines_scrolled < f.ds.get_height() ) { if ( i + lines_scrolled < f.ds.get_height() ) {
*(last_frame.get_row( i )) = *(last_frame.get_row( i + lines_scrolled )); *(frame.last_frame.get_mutable_row( i )) = *(frame.last_frame.get_row( i + lines_scrolled ));
} else { } else {
last_frame.get_row( i )->reset( 0 ); frame.last_frame.get_mutable_row( i )->reset( 0 );
} }
} }
} }
@@ -113,53 +117,53 @@ std::string Display::new_frame( Framebuffer &f )
for ( frame.x = 0; for ( frame.x = 0;
frame.x < f.ds.get_width(); /* let put_cell() handle advance */ ) { frame.x < f.ds.get_width(); /* let put_cell() handle advance */ ) {
last_x = frame.x; last_x = frame.x;
put_cell( frame, f ); put_cell( initialized, frame, f );
/* To hint that a word-select should group the end of one line /* To hint that a word-select should group the end of one line
with the beginning of the next, we let the real cursor with the beginning of the next, we let the real cursor
actually wrap around in cases where it wrapped around for us. */ actually wrap around in cases where it wrapped around for us. */
if ( (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 )->wrap
&& (!initialized || !last_frame.get_row( frame.y )->wrap) ) { && (!initialized || !frame.last_frame.get_row( frame.y )->wrap) ) {
/* next write will wrap */ /* next write will wrap */
cursor_x = 0; frame.cursor_x = 0;
cursor_y++; frame.cursor_y++;
} }
} }
/* 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 )->wrap)
&& (!initialized || last_frame.get_row( frame.y )->wrap) ) { && (!initialized || frame.last_frame.get_row( frame.y )->wrap) ) {
frame.x = last_x; frame.x = last_x;
if ( initialized ) { if ( initialized ) {
last_frame.reset_cell( last_frame.get_cell( frame.y, frame.x ) ); frame.last_frame.reset_cell( frame.last_frame.get_mutable_cell( frame.y, frame.x ) );
} }
snprintf( tmp, 64, "\033[%d;%dH\033[K", frame.y + 1, frame.x + 1 ); snprintf( tmp, 64, "\033[%d;%dH\033[K", frame.y + 1, frame.x + 1 );
frame.append( tmp ); frame.append( tmp );
cursor_x = frame.x; frame.cursor_x = frame.x;
put_cell( frame, f ); put_cell( initialized, frame, f );
} }
} }
/* has cursor location changed? */ /* has cursor location changed? */
if ( (!initialized) if ( (!initialized)
|| (f.ds.get_cursor_row() != cursor_y) || (f.ds.get_cursor_row() != frame.cursor_y)
|| (f.ds.get_cursor_col() != cursor_x) ) { || (f.ds.get_cursor_col() != frame.cursor_x) ) {
snprintf( tmp, 64, "\033[%d;%dH", f.ds.get_cursor_row() + 1, snprintf( tmp, 64, "\033[%d;%dH", f.ds.get_cursor_row() + 1,
f.ds.get_cursor_col() + 1 ); f.ds.get_cursor_col() + 1 );
frame.append( tmp ); frame.append( tmp );
cursor_x = f.ds.get_cursor_col(); frame.cursor_x = f.ds.get_cursor_col();
cursor_y = f.ds.get_cursor_row(); frame.cursor_y = f.ds.get_cursor_row();
} }
/* has cursor visibility changed? */ /* has cursor visibility changed? */
if ( (!initialized) if ( (!initialized)
|| (f.ds.cursor_visible != last_frame.ds.cursor_visible) ) { || (f.ds.cursor_visible != frame.last_frame.ds.cursor_visible) ) {
if ( f.ds.cursor_visible ) { if ( f.ds.cursor_visible ) {
frame.append( "\033[?25h" ); frame.append( "\033[?25h" );
} else { } else {
@@ -167,44 +171,48 @@ std::string Display::new_frame( Framebuffer &f )
} }
} }
last_frame = f; /* have renditions changed? */
initialized = true; if ( (!initialized)
|| (f.ds.get_renditions().sgr() != frame.current_rendition_string) ) {
frame.append( f.ds.get_renditions().sgr() );
frame.current_rendition_string = f.ds.get_renditions().sgr();
}
return frame.str; return frame.str;
} }
void Display::put_cell( FrameState &frame, Framebuffer &f ) void Display::put_cell( bool initialized, FrameState &frame, const Framebuffer &f )
{ {
char tmp[ 64 ]; char tmp[ 64 ];
Cell *cell = f.get_cell( frame.y, frame.x ); const Cell *cell = f.get_cell( frame.y, frame.x );
if ( initialized if ( initialized
&& ( *cell == *(last_frame.get_cell( frame.y, frame.x )) ) ) { && ( *cell == *(frame.last_frame.get_cell( frame.y, frame.x )) ) ) {
frame.x += cell->width; frame.x += cell->width;
return; return;
} }
if ( (frame.x != cursor_x) || (frame.y != cursor_y) ) { if ( (frame.x != frame.cursor_x) || (frame.y != frame.cursor_y) ) {
snprintf( tmp, 64, "\033[%d;%dH", frame.y + 1, frame.x + 1 ); snprintf( tmp, 64, "\033[%d;%dH", frame.y + 1, frame.x + 1 );
frame.append( tmp ); frame.append( tmp );
cursor_x = frame.x; frame.cursor_x = frame.x;
cursor_y = frame.y; frame.cursor_y = frame.y;
} }
std::string rendition_str = cell->renditions.sgr(); std::string rendition_str = cell->renditions.sgr();
if ( current_rendition_string != rendition_str ) { if ( frame.current_rendition_string != rendition_str ) {
/* print renditions */ /* print renditions */
frame.append( rendition_str ); frame.append( rendition_str );
current_rendition_string = rendition_str; frame.current_rendition_string = rendition_str;
} }
if ( cell->contents.empty() ) { if ( cell->contents.empty() ) {
/* see how far we can stretch a clear */ /* see how far we can stretch a clear */
int clear_count = 0; int clear_count = 0;
for ( int col = frame.x; col < f.ds.get_width(); col++ ) { for ( int col = frame.x; col < f.ds.get_width(); col++ ) {
Cell *other_cell = f.get_cell( frame.y, col ); const Cell *other_cell = f.get_cell( frame.y, col );
if ( (cell->renditions == other_cell->renditions) if ( (cell->renditions == other_cell->renditions)
&& (other_cell->contents.empty()) ) { && (other_cell->contents.empty()) ) {
clear_count++; clear_count++;
@@ -225,7 +233,7 @@ void Display::put_cell( FrameState &frame, Framebuffer &f )
frame.append( tmp ); frame.append( tmp );
} }
for ( std::vector<wchar_t>::iterator i = cell->contents.begin(); for ( std::vector<wchar_t>::const_iterator i = cell->contents.begin();
i != cell->contents.end(); i != cell->contents.end();
i++ ) { i++ ) {
snprintf( tmp, 64, "%lc", *i ); snprintf( tmp, 64, "%lc", *i );
@@ -233,5 +241,5 @@ void Display::put_cell( FrameState &frame, Framebuffer &f )
} }
frame.x += cell->width; frame.x += cell->width;
cursor_x += cell->width; frame.cursor_x += cell->width;
} }
+9 -13
View File
@@ -10,27 +10,23 @@ namespace Terminal {
int x, y; int x, y;
std::string str; std::string str;
FrameState() : x(0), y(0), str() {} int cursor_x, cursor_y;
std::string current_rendition_string;
Framebuffer last_frame;
FrameState( const Framebuffer &s_last ) : x(0), y(0), str(), cursor_x(0), cursor_y(0), current_rendition_string(), last_frame( s_last ) {}
void append( std::string s ) { str.append( s ); } void append( std::string s ) { str.append( s ); }
}; };
class Display { class Display {
private: private:
bool initialized; void put_cell( bool initialized, FrameState &frame, const Framebuffer &f );
Framebuffer last_frame;
std::string current_rendition_string;
int cursor_x, cursor_y;
void put_cell( FrameState &frame, Framebuffer &f );
public: public:
Display( int width, int height ) Display() {}
: initialized( false ), last_frame( width, height ),
current_rendition_string(), cursor_x( -1 ), cursor_y( -1 )
{}
std::string new_frame( Framebuffer &f ); std::string new_frame( bool initialized, const Framebuffer &last, const Framebuffer &f );
void invalidate( void ) { initialized = false; }
}; };
} }
+2 -2
View File
@@ -199,7 +199,7 @@ std::vector<int> DrawState::get_tabs( void )
void Framebuffer::apply_renditions_to_current_cell( void ) void Framebuffer::apply_renditions_to_current_cell( void )
{ {
get_cell()->renditions = ds.get_renditions(); get_mutable_cell()->renditions = ds.get_renditions();
} }
SavedCursor::SavedCursor() SavedCursor::SavedCursor()
@@ -373,7 +373,7 @@ void Renditions::set_rendition( int num )
} }
} }
std::string Renditions::sgr( void ) std::string Renditions::sgr( void ) const
{ {
std::string ret; std::string ret;
+33 -27
View File
@@ -18,7 +18,7 @@ namespace Terminal {
Renditions( int s_background ); Renditions( int s_background );
void set_rendition( int num ); void set_rendition( int num );
std::string sgr( void ); std::string sgr( void ) const;
bool operator==( const Renditions &x ) const bool operator==( const Renditions &x ) const
{ {
@@ -119,12 +119,12 @@ namespace Terminal {
void move_row( int N, bool relative = false ); void move_row( int N, bool relative = false );
void move_col( int N, bool relative = false, bool implicit = false ); void move_col( int N, bool relative = false, bool implicit = false );
int get_cursor_col( void ) { return cursor_col; } int get_cursor_col( void ) const { return cursor_col; }
int get_cursor_row( void ) { return cursor_row; } int get_cursor_row( void ) const { return cursor_row; }
int get_combining_char_col( void ) { return combining_char_col; } int get_combining_char_col( void ) const { return combining_char_col; }
int get_combining_char_row( void ) { return combining_char_row; } int get_combining_char_row( void ) const { return combining_char_row; }
int get_width( void ) { return width; } int get_width( void ) const { return width; }
int get_height( void ) { return height; } int get_height( void ) const { return height; }
void set_tab( void ); void set_tab( void );
void clear_tab( int col ); void clear_tab( int col );
@@ -134,14 +134,14 @@ namespace Terminal {
void set_scrolling_region( int top, int bottom ); void set_scrolling_region( int top, int bottom );
int get_scrolling_region_top_row( void ) { return scrolling_region_top_row; } int get_scrolling_region_top_row( void ) const { return scrolling_region_top_row; }
int get_scrolling_region_bottom_row( void ) { return scrolling_region_bottom_row; } int get_scrolling_region_bottom_row( void ) const { return scrolling_region_bottom_row; }
int limit_top( void ); int limit_top( void );
int limit_bottom( void ); int limit_bottom( void );
void add_rendition( int x ) { renditions.set_rendition( x ); } void add_rendition( int x ) { renditions.set_rendition( x ); }
Renditions get_renditions( void ) { return renditions; } Renditions get_renditions( void ) const { return renditions; }
int get_background_rendition( void ) { return renditions.background_color; } int get_background_rendition( void ) { return renditions.background_color; }
void save_cursor( void ); void save_cursor( void );
@@ -167,36 +167,42 @@ namespace Terminal {
void scroll( int N ); void scroll( int N );
void move_rows_autoscroll( int rows ); void move_rows_autoscroll( int rows );
Row *get_row( int row ) const Row *get_row( int row ) const
{ {
if ( row == -1 ) row = ds.get_cursor_row(); if ( row == -1 ) row = ds.get_cursor_row();
return &rows[ row ]; return &rows[ row ];
} }
inline Cell *get_cell( void ) inline const Cell *get_cell( void ) const
{ {
#ifdef DEBUG
assert( ds.get_cursor_row() >= 0 );
assert( ds.get_cursor_col() >= 0 );
assert( ds.get_cursor_row() < ds.get_height() );
assert( ds.get_cursor_col() < ds.get_width() );
#endif
return &rows[ ds.get_cursor_row() ].cells[ ds.get_cursor_col() ]; return &rows[ ds.get_cursor_row() ].cells[ ds.get_cursor_col() ];
} }
inline Cell *get_cell( int row, int col ) inline const Cell *get_cell( int row, int col ) const
{ {
if ( row == -1 ) row = ds.get_cursor_row(); if ( row == -1 ) row = ds.get_cursor_row();
if ( col == -1 ) col = ds.get_cursor_col(); if ( col == -1 ) col = ds.get_cursor_col();
#ifdef DEBUG return &rows[ row ].cells[ col ];
assert( row >= 0 ); }
assert( col >= 0 );
assert( row < ds.get_height() ); Row *get_mutable_row( int row )
assert( col < ds.get_width() ); {
#endif if ( row == -1 ) row = ds.get_cursor_row();
return &rows[ row ];
}
inline Cell *get_mutable_cell( void )
{
return &rows[ ds.get_cursor_row() ].cells[ ds.get_cursor_col() ];
}
inline Cell *get_mutable_cell( int row, int col )
{
if ( row == -1 ) row = ds.get_cursor_row();
if ( col == -1 ) col = ds.get_cursor_col();
return &rows[ row ].cells[ col ]; return &rows[ row ].cells[ col ];
} }
@@ -215,7 +221,7 @@ namespace Terminal {
void soft_reset( void ); void soft_reset( void );
void set_window_title( std::vector<wchar_t> s ) { window_title = s; } void set_window_title( std::vector<wchar_t> s ) { window_title = s; }
std::vector<wchar_t> get_window_title( void ) { return window_title; } std::vector<wchar_t> get_window_title( void ) const { return window_title; }
void resize( int s_width, int s_height ); void resize( int s_width, int s_height );
+8 -8
View File
@@ -12,7 +12,7 @@ using namespace Terminal;
static void clearline( Framebuffer *fb, int row, int start, int end ) static void clearline( Framebuffer *fb, int row, int start, int end )
{ {
for ( int col = start; col <= end; col++ ) { for ( int col = start; col <= end; col++ ) {
fb->reset_cell( fb->get_cell( row, col ) ); fb->reset_cell( fb->get_mutable_cell( row, col ) );
} }
} }
@@ -27,7 +27,7 @@ void CSI_EL( Framebuffer *fb, Dispatcher *dispatch )
clearline( fb, -1, 0, fb->ds.get_cursor_col() ); clearline( fb, -1, 0, fb->ds.get_cursor_col() );
break; break;
case 2: /* all of line */ case 2: /* all of line */
fb->reset_row( fb->get_row( -1 ) ); fb->reset_row( fb->get_mutable_row( -1 ) );
break; break;
} }
} }
@@ -40,18 +40,18 @@ void CSI_ED( Framebuffer *fb, Dispatcher *dispatch ) {
case 0: /* active position to end of screen, inclusive */ case 0: /* active position to end of screen, inclusive */
clearline( fb, -1, fb->ds.get_cursor_col(), fb->ds.get_width() - 1 ); clearline( fb, -1, fb->ds.get_cursor_col(), fb->ds.get_width() - 1 );
for ( int y = fb->ds.get_cursor_row() + 1; y < fb->ds.get_height(); y++ ) { for ( int y = fb->ds.get_cursor_row() + 1; y < fb->ds.get_height(); y++ ) {
fb->reset_row( fb->get_row( y ) ); fb->reset_row( fb->get_mutable_row( y ) );
} }
break; break;
case 1: /* start of screen to active position, inclusive */ case 1: /* start of screen to active position, inclusive */
for ( int y = 0; y < fb->ds.get_cursor_row(); y++ ) { for ( int y = 0; y < fb->ds.get_cursor_row(); y++ ) {
fb->reset_row( fb->get_row( y ) ); fb->reset_row( fb->get_mutable_row( y ) );
} }
clearline( fb, -1, 0, fb->ds.get_cursor_col() ); clearline( fb, -1, 0, fb->ds.get_cursor_col() );
break; break;
case 2: /* entire screen */ case 2: /* entire screen */
for ( int y = 0; y < fb->ds.get_height(); y++ ) { for ( int y = 0; y < fb->ds.get_height(); y++ ) {
fb->reset_row( fb->get_row( y ) ); fb->reset_row( fb->get_mutable_row( y ) );
} }
break; break;
} }
@@ -114,8 +114,8 @@ void Esc_DECALN( Framebuffer *fb, Dispatcher *dispatch __attribute((unused)) )
{ {
for ( int y = 0; y < fb->ds.get_height(); y++ ) { for ( int y = 0; y < fb->ds.get_height(); y++ ) {
for ( int x = 0; x < fb->ds.get_width(); x++ ) { for ( int x = 0; x < fb->ds.get_width(); x++ ) {
fb->reset_cell( fb->get_cell( y, x ) ); fb->reset_cell( fb->get_mutable_cell( y, x ) );
fb->get_cell( y, x )->contents.push_back( L'E' ); fb->get_mutable_cell( y, x )->contents.push_back( L'E' );
} }
} }
} }
@@ -215,7 +215,7 @@ static bool *get_DEC_mode( int param, Framebuffer *fb ) {
fb->ds.move_row( 0 ); fb->ds.move_row( 0 );
fb->ds.move_col( 0 ); fb->ds.move_col( 0 );
for ( int y = 0; y < fb->ds.get_height(); y++ ) { for ( int y = 0; y < fb->ds.get_height(); y++ ) {
fb->reset_row( fb->get_row( y ) ); fb->reset_row( fb->get_mutable_row( y ) );
} }
return NULL; return NULL;
case 5: /* reverse video */ case 5: /* reverse video */