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
+52 -44
View File
@@ -6,15 +6,15 @@ using namespace Terminal;
/* 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 ];
/* has window title changed? */
if ( (!initialized)
|| (f.get_window_title() != last_frame.get_window_title()) ) {
|| (f.get_window_title() != frame.last_frame.get_window_title()) ) {
/* set window title */
frame.append( "\033]0;[stm] " );
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? */
if ( (!initialized)
|| (f.ds.reverse_video != last_frame.ds.reverse_video) ) {
|| (f.ds.reverse_video != frame.last_frame.ds.reverse_video) ) {
/* set reverse video */
snprintf( tmp, 64, "\033[?5%c", (f.ds.reverse_video ? 'h' : 'l') );
frame.append( tmp );
@@ -37,13 +37,17 @@ std::string Display::new_frame( Framebuffer &f )
/* has size changed? */
if ( (!initialized)
|| (f.ds.get_width() != last_frame.ds.get_width())
|| (f.ds.get_height() != last_frame.ds.get_height()) ) {
|| (f.ds.get_width() != frame.last_frame.ds.get_width())
|| (f.ds.get_height() != frame.last_frame.ds.get_height()) ) {
/* clear screen */
frame.append( "\033[0m\033[H\033[2J" );
initialized = false;
cursor_x = cursor_y = 0;
current_rendition_string = "\033[0m";
frame.cursor_x = frame.cursor_y = 0;
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? */
@@ -54,7 +58,7 @@ std::string Display::new_frame( Framebuffer &f )
int scroll_height = 0;
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 */
lines_scrolled = row;
scroll_height = 1;
@@ -64,7 +68,7 @@ std::string Display::new_frame( Framebuffer &f )
lines_scrolled + region_height < f.ds.get_height();
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;
} else {
break;
@@ -79,17 +83,17 @@ std::string Display::new_frame( Framebuffer &f )
frame.y = scroll_height;
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 );
frame.append( tmp );
cursor_y = f.ds.get_height() - 1;
cursor_x = 0;
frame.cursor_y = f.ds.get_height() - 1;
frame.cursor_x = 0;
}
if ( current_rendition_string != "\033[0m" ) {
if ( frame.current_rendition_string != "\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++ ) {
@@ -98,9 +102,9 @@ std::string Display::new_frame( Framebuffer &f )
for ( int i = 0; i < f.ds.get_height(); i++ ) {
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 {
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;
frame.x < f.ds.get_width(); /* let put_cell() handle advance */ ) {
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
with the beginning of the next, we let the real cursor
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)
&& 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 */
cursor_x = 0;
cursor_y++;
frame.cursor_x = 0;
frame.cursor_y++;
}
}
/* Turn off wrap */
if ( (frame.y < f.ds.get_height() - 1)
&& (!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;
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 );
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? */
if ( (!initialized)
|| (f.ds.get_cursor_row() != cursor_y)
|| (f.ds.get_cursor_col() != cursor_x) ) {
|| (f.ds.get_cursor_row() != frame.cursor_y)
|| (f.ds.get_cursor_col() != frame.cursor_x) ) {
snprintf( tmp, 64, "\033[%d;%dH", f.ds.get_cursor_row() + 1,
f.ds.get_cursor_col() + 1 );
frame.append( tmp );
cursor_x = f.ds.get_cursor_col();
cursor_y = f.ds.get_cursor_row();
frame.cursor_x = f.ds.get_cursor_col();
frame.cursor_y = f.ds.get_cursor_row();
}
/* has cursor visibility changed? */
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 ) {
frame.append( "\033[?25h" );
} else {
@@ -167,44 +171,48 @@ std::string Display::new_frame( Framebuffer &f )
}
}
last_frame = f;
initialized = true;
/* have renditions changed? */
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;
}
void Display::put_cell( FrameState &frame, Framebuffer &f )
void Display::put_cell( bool initialized, FrameState &frame, const Framebuffer &f )
{
char tmp[ 64 ];
Cell *cell = f.get_cell( frame.y, frame.x );
const Cell *cell = f.get_cell( frame.y, frame.x );
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;
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 );
frame.append( tmp );
cursor_x = frame.x;
cursor_y = frame.y;
frame.cursor_x = frame.x;
frame.cursor_y = frame.y;
}
std::string rendition_str = cell->renditions.sgr();
if ( current_rendition_string != rendition_str ) {
if ( frame.current_rendition_string != rendition_str ) {
/* print renditions */
frame.append( rendition_str );
current_rendition_string = rendition_str;
frame.current_rendition_string = rendition_str;
}
if ( cell->contents.empty() ) {
/* see how far we can stretch a clear */
int clear_count = 0;
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)
&& (other_cell->contents.empty()) ) {
clear_count++;
@@ -225,7 +233,7 @@ void Display::put_cell( FrameState &frame, Framebuffer &f )
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++ ) {
snprintf( tmp, 64, "%lc", *i );
@@ -233,5 +241,5 @@ void Display::put_cell( FrameState &frame, Framebuffer &f )
}
frame.x += cell->width;
cursor_x += cell->width;
frame.cursor_x += cell->width;
}