From ad29a350d6e53c6a327cd76f8ee26fe1e450781d Mon Sep 17 00:00:00 2001 From: Keith Winstein Date: Mon, 31 Jan 2011 23:16:17 -0500 Subject: [PATCH] Color support (and bold and other renditions) --- terminal.cpp | 15 +++++++++++++++ terminalframebuffer.cpp | 18 ++++++++++++++++-- terminalframebuffer.hpp | 8 ++++++++ terminalfunctions.cpp | 15 +++++++++++++++ 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/terminal.cpp b/terminal.cpp index 1481ea4..c7155f9 100644 --- a/terminal.cpp +++ b/terminal.cpp @@ -77,6 +77,7 @@ void Emulator::print( Parser::Print *act ) this_cell->reset(); this_cell->contents.push_back( act->ch ); this_cell->width = chwidth; + fb.apply_renditions_to_current_cell(); fb.claim_overlap( fb.ds.get_cursor_row(), fb.ds.get_cursor_col() ); @@ -143,6 +144,20 @@ void Emulator::debug_printout( int fd ) assert( (cell->overlapped_cells.size() + 1 == (size_t)cell->width) || (x == fb.ds.get_width() - 1) ); + /* print renditions */ + screen.append( "\033[0" ); + char rendition[ 32 ]; + for ( std::vector::iterator i = cell->renditions.begin(); + i != cell->renditions.end(); + i++ ) { + snprintf( rendition, 32, ";%d", *i ); + screen.append( rendition ); + } + screen.append( "m" ); + + /* print cell contents */ + + /* cells that begin with combining character get combiner attached to no-break space */ if ( cell->fallback ) { char utf8[ 8 ]; snprintf( utf8, 8, "%lc", 0xA0 ); diff --git a/terminalframebuffer.cpp b/terminalframebuffer.cpp index b19c05a..a60c1d4 100644 --- a/terminalframebuffer.cpp +++ b/terminalframebuffer.cpp @@ -9,7 +9,8 @@ Cell::Cell() contents(), overlapped_cells(), fallback( false ), - width( 1 ) + width( 1 ), + renditions() {} Cell::Cell( const Cell &x ) @@ -17,7 +18,8 @@ Cell::Cell( const Cell &x ) contents( x.contents ), overlapped_cells( x.overlapped_cells ), fallback( x.fallback ), - width( 1 ) + width( x.width ), + renditions( x.renditions ) {} Cell & Cell::operator=( const Cell &x ) @@ -26,6 +28,8 @@ Cell & Cell::operator=( const Cell &x ) contents = x.contents; overlapped_cells = x.overlapped_cells; fallback = x.fallback; + width = x.width; + renditions = x.renditions; return *this; } @@ -39,6 +43,7 @@ void Cell::reset( void ) contents.clear(); fallback = false; width = 1; + renditions.clear(); if ( overlapping_cell ) { assert( overlapped_cells.size() == 0 ); @@ -58,6 +63,7 @@ DrawState::DrawState( int s_width, int s_height ) cursor_col( 0 ), cursor_row( 0 ), combining_char_col( 0 ), combining_char_row( 0 ), tabs( s_width ), scrolling_region_top_row( 0 ), scrolling_region_bottom_row( height - 1 ), + renditions(), next_print_will_wrap( false ), origin_mode( false ), auto_wrap_mode( true ) { for ( int i = 0; i < width; i++ ) { @@ -256,3 +262,11 @@ std::vector DrawState::get_tabs( void ) return ret; } + +void Framebuffer::apply_renditions_to_current_cell( void ) +{ + Cell *this_cell = get_cell(); + assert( this_cell ); + + this_cell->renditions = ds.get_renditions(); +} diff --git a/terminalframebuffer.hpp b/terminalframebuffer.hpp index c71984a..ea5db22 100644 --- a/terminalframebuffer.hpp +++ b/terminalframebuffer.hpp @@ -14,6 +14,7 @@ namespace Terminal { std::vector overlapped_cells; char fallback; /* first character is combining character */ int width; + std::vector renditions; /* e.g., bold, blinking, etc. */ Cell(); @@ -44,6 +45,8 @@ namespace Terminal { int scrolling_region_top_row, scrolling_region_bottom_row; + std::vector renditions; + public: bool next_print_will_wrap; bool origin_mode; @@ -75,6 +78,10 @@ namespace Terminal { int limit_top( void ); int limit_bottom( void ); + void clear_renditions( void ) { renditions.clear(); } + void add_rendition( int x ) { renditions.push_back( x ); } + const std::vector get_renditions( void ) { return renditions; } + DrawState( int s_width, int s_height ); }; @@ -94,6 +101,7 @@ namespace Terminal { Cell *get_cell( int row, int col ); Cell *get_combining_cell( void ); + void apply_renditions_to_current_cell( void ); void claim_overlap( int row, int col ); }; } diff --git a/terminalfunctions.cpp b/terminalfunctions.cpp index 9ebb970..569e2be 100644 --- a/terminalfunctions.cpp +++ b/terminalfunctions.cpp @@ -259,3 +259,18 @@ void Ctrl_BEL( Framebuffer *fb __attribute((unused)), Dispatcher *dispatch __att {} static Function func_Ctrl_BEL( CONTROL, "\x07", Ctrl_BEL ); + +/* select graphics rendition -- e.g., bold, blinking, etc. */ +void CSI_SGR( Framebuffer *fb, Dispatcher *dispatch ) +{ + for ( int i = 0; i < dispatch->param_count(); i++ ) { + int rendition = dispatch->getparam( i, 0 ); + if ( rendition == 0 ) { + fb->ds.clear_renditions(); + } else { + fb->ds.add_rendition( rendition ); + } + } +} + +static Function func_CSI_SGR( CSI, "m", CSI_SGR );