Change Framebuffer's containers/methods to improve performance.
* Reduce the size of Terminal::Cell. * Change colors and attributes in Terminal::Rendition to bitfields/bitmask. * Change Cells to use UTF-8 strings instead of vector<wchar_t>. Store Rows in a vector instead of a deque. * Add various Framebuffer::append() methods for more efficient passing of single and repeated characters. * Change title/icon strings from deques to a vector typedef-- this is more for tidiness than any real performance.
This commit is contained in:
@@ -61,15 +61,15 @@ void ConditionalOverlayCell::apply( Framebuffer &fb, uint64_t confirmed_epoch, i
|
||||
|
||||
if ( unknown ) {
|
||||
if ( flag && ( col != fb.ds.get_width() - 1 ) ) {
|
||||
fb.get_mutable_cell( row, col )->renditions.underlined = true;
|
||||
fb.get_mutable_cell( row, col )->renditions.set_attribute(Renditions::underlined, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !(*(fb.get_cell( row, col )) == replacement) ) {
|
||||
if ( *fb.get_cell( row, col ) != replacement ) {
|
||||
*(fb.get_mutable_cell( row, col )) = replacement;
|
||||
if ( flag ) {
|
||||
fb.get_mutable_cell( row, col )->renditions.underlined = true;
|
||||
fb.get_mutable_cell( row, col )->renditions.set_attribute( Renditions::underlined, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -275,7 +275,7 @@ void NotificationEngine::apply( Framebuffer &fb ) const
|
||||
case 2: /* wide character */
|
||||
this_cell = fb.get_mutable_cell( 0, overlay_col );
|
||||
fb.reset_cell( this_cell );
|
||||
this_cell->renditions.bold = true;
|
||||
this_cell->renditions.set_attribute(Renditions::bold, true);
|
||||
this_cell->renditions.foreground_color = 37;
|
||||
this_cell->renditions.background_color = 44;
|
||||
|
||||
@@ -296,7 +296,7 @@ void NotificationEngine::apply( Framebuffer &fb ) const
|
||||
overlay_col++;
|
||||
}
|
||||
|
||||
if ( combining_cell->contents.size() < 16 ) {
|
||||
if ( combining_cell->contents.size() < 32 ) {
|
||||
combining_cell->contents.push_back( ch );
|
||||
}
|
||||
break;
|
||||
@@ -345,9 +345,9 @@ void OverlayManager::apply( Framebuffer &fb )
|
||||
title.apply( fb );
|
||||
}
|
||||
|
||||
void TitleEngine::set_prefix( const wstring s )
|
||||
void TitleEngine::set_prefix( const wstring &s )
|
||||
{
|
||||
prefix = deque<wchar_t>( s.begin(), s.end() );
|
||||
prefix = Terminal::Framebuffer::title_type( s.begin(), s.end() );
|
||||
}
|
||||
|
||||
void ConditionalOverlayRow::apply( Framebuffer &fb, uint64_t confirmed_epoch, bool flag ) const
|
||||
|
||||
@@ -310,12 +310,12 @@ namespace Overlay {
|
||||
|
||||
class TitleEngine {
|
||||
private:
|
||||
deque<wchar_t> prefix;
|
||||
Terminal::Framebuffer::title_type prefix;
|
||||
|
||||
public:
|
||||
void apply( Framebuffer &fb ) const { fb.prefix_window_title( prefix ); }
|
||||
void set_prefix( const wstring s );
|
||||
TitleEngine() : prefix() {}
|
||||
void set_prefix( const wstring &s );
|
||||
};
|
||||
|
||||
/* the overlay manager */
|
||||
@@ -331,7 +331,7 @@ namespace Overlay {
|
||||
NotificationEngine & get_notification_engine( void ) { return notifications; }
|
||||
PredictionEngine & get_prediction_engine( void ) { return predictions; }
|
||||
|
||||
void set_title_prefix( const wstring s ) { title.set_prefix( s ); }
|
||||
void set_title_prefix( const wstring &s ) { title.set_prefix( s ); }
|
||||
|
||||
OverlayManager() : notifications(), predictions(), title() {}
|
||||
|
||||
|
||||
@@ -85,8 +85,7 @@ void Parser::UTF8Parser::input( char c, Actions &ret )
|
||||
/* This function will only work in a UTF-8 locale. */
|
||||
|
||||
wchar_t pwc;
|
||||
mbstate_t ps;
|
||||
memset( &ps, 0, sizeof( ps ) );
|
||||
mbstate_t ps = mbstate_t();
|
||||
|
||||
size_t total_bytes_parsed = 0;
|
||||
size_t orig_buf_len = buf_len;
|
||||
|
||||
@@ -97,7 +97,7 @@ void Emulator::print( const Parser::Print *act )
|
||||
this_cell = fb.get_mutable_cell();
|
||||
|
||||
fb.reset_cell( this_cell );
|
||||
this_cell->contents.push_back( act->ch );
|
||||
this_cell->append( act->ch );
|
||||
this_cell->width = chwidth;
|
||||
fb.apply_renditions_to_current_cell();
|
||||
|
||||
@@ -127,8 +127,7 @@ void Emulator::print( const Parser::Print *act )
|
||||
combining_cell->fallback = true;
|
||||
fb.ds.move_col( 1, true, true );
|
||||
}
|
||||
|
||||
if ( combining_cell->contents.size() < 16 ) {
|
||||
if ( combining_cell->contents.size() < 32 ) {
|
||||
/* seems like a reasonable limit on combining characters */
|
||||
combining_cell->contents.push_back( act->ch );
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "terminaldisplay.h"
|
||||
#include "terminalframebuffer.h"
|
||||
|
||||
using namespace Terminal;
|
||||
|
||||
@@ -65,7 +66,7 @@ std::string Display::new_frame( bool initialized, const Framebuffer &last, const
|
||||
|
||||
/* has bell been rung? */
|
||||
if ( f.get_bell_count() != frame.last_frame.get_bell_count() ) {
|
||||
frame.append( "\x07" );
|
||||
frame.append( '\007' );
|
||||
}
|
||||
|
||||
/* has icon name or window title changed? */
|
||||
@@ -73,40 +74,38 @@ std::string Display::new_frame( bool initialized, const Framebuffer &last, const
|
||||
( (!initialized)
|
||||
|| (f.get_icon_name() != frame.last_frame.get_icon_name())
|
||||
|| (f.get_window_title() != frame.last_frame.get_window_title()) ) ) {
|
||||
typedef Terminal::Framebuffer::title_type title_type;
|
||||
/* set icon name and window title */
|
||||
if ( f.get_icon_name() == f.get_window_title() ) {
|
||||
/* write combined Icon Name and Window Title */
|
||||
frame.append( "\033]0;" );
|
||||
const std::deque<wchar_t> &window_title( f.get_window_title() );
|
||||
for ( std::deque<wchar_t>::const_iterator i = window_title.begin();
|
||||
const title_type &window_title( f.get_window_title() );
|
||||
for ( title_type::const_iterator i = window_title.begin();
|
||||
i != window_title.end();
|
||||
i++ ) {
|
||||
snprintf( tmp, 64, "%lc", (wint_t)*i );
|
||||
frame.append( tmp );
|
||||
frame.append( *i );
|
||||
}
|
||||
frame.append( "\007" );
|
||||
frame.append( '\007' );
|
||||
/* ST is more correct, but BEL more widely supported */
|
||||
} else {
|
||||
/* write Icon Name */
|
||||
frame.append( "\033]1;" );
|
||||
const std::deque<wchar_t> &icon_name( f.get_icon_name() );
|
||||
for ( std::deque<wchar_t>::const_iterator i = icon_name.begin();
|
||||
const title_type &icon_name( f.get_icon_name() );
|
||||
for ( title_type::const_iterator i = icon_name.begin();
|
||||
i != icon_name.end();
|
||||
i++ ) {
|
||||
snprintf( tmp, 64, "%lc", (wint_t)*i );
|
||||
frame.append( tmp );
|
||||
frame.append( *i );
|
||||
}
|
||||
frame.append( "\007" );
|
||||
frame.append( '\007' );
|
||||
|
||||
frame.append( "\033]2;" );
|
||||
const std::deque<wchar_t> &window_title( f.get_window_title() );
|
||||
for ( std::deque<wchar_t>::const_iterator i = window_title.begin();
|
||||
const title_type &window_title( f.get_window_title() );
|
||||
for ( title_type::const_iterator i = window_title.begin();
|
||||
i != window_title.end();
|
||||
i++ ) {
|
||||
snprintf( tmp, 64, "%lc", (wint_t)*i );
|
||||
frame.append( tmp );
|
||||
frame.append( *i );
|
||||
}
|
||||
frame.append( "\007" );
|
||||
frame.append( '\007' );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -192,7 +191,7 @@ std::string Display::new_frame( bool initialized, const Framebuffer &last, const
|
||||
|
||||
/* scroll */
|
||||
for ( int i = 0; i < lines_scrolled; i++ ) {
|
||||
frame.append( "\n" );
|
||||
frame.append( '\n' );
|
||||
}
|
||||
|
||||
/* do the move in memory */
|
||||
@@ -285,7 +284,7 @@ std::string Display::new_frame( bool initialized, const Framebuffer &last, const
|
||||
/* have renditions changed? */
|
||||
if ( (!initialized)
|
||||
|| !(f.ds.get_renditions() == frame.current_rendition) ) {
|
||||
frame.appendstring( f.ds.get_renditions().sgr() );
|
||||
frame.append( f.ds.get_renditions().sgr() );
|
||||
frame.current_rendition = f.ds.get_renditions();
|
||||
}
|
||||
|
||||
@@ -359,7 +358,7 @@ void Display::put_cell( bool initialized, FrameState &frame, const Framebuffer &
|
||||
|
||||
if ( !(frame.current_rendition == cell->renditions) ) {
|
||||
/* print renditions */
|
||||
frame.appendstring( cell->renditions.sgr() );
|
||||
frame.append( cell->renditions.sgr() );
|
||||
frame.current_rendition = cell->renditions;
|
||||
}
|
||||
|
||||
@@ -381,7 +380,7 @@ void Display::put_cell( bool initialized, FrameState &frame, const Framebuffer &
|
||||
bool can_use_erase = has_bce || (cell->renditions == initial_rendition());
|
||||
|
||||
if ( frame.force_next_put ) {
|
||||
frame.append( " " );
|
||||
frame.append( ' ' );
|
||||
frame.cursor_x++;
|
||||
frame.x++;
|
||||
frame.force_next_put = false;
|
||||
@@ -404,7 +403,7 @@ void Display::put_cell( bool initialized, FrameState &frame, const Framebuffer &
|
||||
frame.x += clear_count;
|
||||
} else { /* no ECH, so just print a space */
|
||||
/* unlike erases, this will use background color irrespective of BCE */
|
||||
frame.append( " " );
|
||||
frame.append( ' ' );
|
||||
frame.cursor_x++;
|
||||
frame.x++;
|
||||
}
|
||||
@@ -418,12 +417,7 @@ void Display::put_cell( bool initialized, FrameState &frame, const Framebuffer &
|
||||
frame.append( "\xC2\xA0" );
|
||||
}
|
||||
|
||||
for ( std::vector<wchar_t>::const_iterator i = cell->contents.begin();
|
||||
i != cell->contents.end();
|
||||
i++ ) {
|
||||
snprintf( tmp, 64, "%lc", (wint_t)*i );
|
||||
frame.append( tmp );
|
||||
}
|
||||
frame.append( cell->contents );
|
||||
|
||||
frame.x += cell->width;
|
||||
frame.cursor_x += cell->width;
|
||||
@@ -446,3 +440,13 @@ void FrameState::append_silent_move( int y, int x )
|
||||
cursor_x = x;
|
||||
cursor_y = y;
|
||||
}
|
||||
|
||||
FrameState::FrameState( const Framebuffer &s_last )
|
||||
: x(0), y(0),
|
||||
force_next_put( false ),
|
||||
str(), cursor_x(0), cursor_y(0), current_rendition( 0 ),
|
||||
last_frame( s_last )
|
||||
{
|
||||
/* just a guess-- doesn't matter for correctness */
|
||||
str.reserve( last_frame.ds.get_width() * last_frame.ds.get_height() * 4 );
|
||||
}
|
||||
|
||||
@@ -48,17 +48,13 @@ namespace Terminal {
|
||||
|
||||
Framebuffer last_frame;
|
||||
|
||||
FrameState( const Framebuffer &s_last )
|
||||
: x(0), y(0),
|
||||
force_next_put( false ),
|
||||
str(), cursor_x(0), cursor_y(0), current_rendition( 0 ),
|
||||
last_frame( s_last )
|
||||
{
|
||||
str.reserve( 1024 );
|
||||
}
|
||||
FrameState( const Framebuffer &s_last );
|
||||
|
||||
void append( const char c ) { str.append( 1, c ); }
|
||||
void append( const wchar_t wc ) { Cell::append_to_str( str, wc ); }
|
||||
void append( const char * s ) { str.append( s ); }
|
||||
void appendstring( const std::string &s ) { str.append( s ); }
|
||||
void append( const Cell::content_type &contents ) { str.append( contents.begin(), contents.end() ); }
|
||||
void append_string( const std::string &append ) { str.append(append); }
|
||||
|
||||
void append_silent_move( int y, int x );
|
||||
};
|
||||
|
||||
@@ -90,7 +90,7 @@ const char *Display::ti_str( const char *capname )
|
||||
}
|
||||
|
||||
Display::Display( bool use_environment )
|
||||
: has_ech( true ), has_bce( true ), has_title( true ), posterize_colors( false ), smcup( NULL ), rmcup( NULL )
|
||||
: has_ech( true ), has_bce( true ), has_title( true ), posterize_colors( 0 ), smcup( NULL ), rmcup( NULL )
|
||||
{
|
||||
if ( use_environment ) {
|
||||
int errret = -2;
|
||||
|
||||
@@ -32,17 +32,37 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "terminalframebuffer.h"
|
||||
|
||||
using namespace Terminal;
|
||||
|
||||
void Cell::reset( int background_color )
|
||||
Cell::Cell( color_type background_color )
|
||||
: contents(),
|
||||
renditions( background_color ),
|
||||
width( 1 ),
|
||||
fallback( false ),
|
||||
wrap( false )
|
||||
{}
|
||||
#if 0
|
||||
Cell::Cell() /* default constructor required by C++11 STL */
|
||||
: contents(),
|
||||
renditions( 0 ),
|
||||
width( 1 ),
|
||||
fallback( false ),
|
||||
wrap( false )
|
||||
{
|
||||
assert( false );
|
||||
}
|
||||
#endif
|
||||
|
||||
void Cell::reset( color_type background_color )
|
||||
{
|
||||
contents.clear();
|
||||
fallback = false;
|
||||
width = 1;
|
||||
renditions = Renditions( background_color );
|
||||
width = 1;
|
||||
fallback = false;
|
||||
wrap = false;
|
||||
}
|
||||
|
||||
@@ -310,13 +330,25 @@ void Framebuffer::delete_line( int row, int count )
|
||||
}
|
||||
}
|
||||
|
||||
void Row::insert_cell( int col, int background_color )
|
||||
Row::Row( size_t s_width, color_type background_color )
|
||||
: cells( s_width, Cell( background_color ) )
|
||||
{}
|
||||
|
||||
#if 0
|
||||
Row::Row() /* default constructor required by C++11 STL */
|
||||
: cells( 1, Cell() )
|
||||
{
|
||||
assert( false );
|
||||
}
|
||||
#endif
|
||||
|
||||
void Row::insert_cell( int col, color_type background_color )
|
||||
{
|
||||
cells.insert( cells.begin() + col, Cell( background_color ) );
|
||||
cells.pop_back();
|
||||
}
|
||||
|
||||
void Row::delete_cell( int col, int background_color )
|
||||
void Row::delete_cell( int col, color_type background_color )
|
||||
{
|
||||
cells.push_back( Cell( background_color ) );
|
||||
cells.erase( cells.begin() + col );
|
||||
@@ -336,7 +368,7 @@ void Framebuffer::reset( void )
|
||||
{
|
||||
int width = ds.get_width(), height = ds.get_height();
|
||||
ds = DrawState( width, height );
|
||||
rows = std::deque<Row>( height, newrow() );
|
||||
rows = rows_type( height, newrow() );
|
||||
window_title.clear();
|
||||
/* do not reset bell_count */
|
||||
}
|
||||
@@ -412,17 +444,16 @@ void DrawState::resize( int s_width, int s_height )
|
||||
}
|
||||
}
|
||||
|
||||
Renditions::Renditions( int s_background )
|
||||
: bold( false ), italic( false ), underlined( false ), blink( false ),
|
||||
inverse( false ), invisible( false ), foreground_color( 0 ),
|
||||
background_color( s_background )
|
||||
Renditions::Renditions( color_type s_background )
|
||||
: foreground_color( 0 ), background_color( s_background ),
|
||||
attributes( 0 )
|
||||
{}
|
||||
|
||||
/* This routine cannot be used to set a color beyond the 16-color set. */
|
||||
void Renditions::set_rendition( int num )
|
||||
void Renditions::set_rendition( color_type num )
|
||||
{
|
||||
if ( num == 0 ) {
|
||||
bold = italic = underlined = blink = inverse = invisible = false;
|
||||
clear_attributes();
|
||||
foreground_color = background_color = 0;
|
||||
return;
|
||||
}
|
||||
@@ -449,13 +480,14 @@ void Renditions::set_rendition( int num )
|
||||
return;
|
||||
}
|
||||
|
||||
bool value = num < 9;
|
||||
switch ( num ) {
|
||||
case 1: case 22: bold = (num == 1); break;
|
||||
case 3: case 23: italic = (num == 3); break;
|
||||
case 4: case 24: underlined = (num == 4); break;
|
||||
case 5: case 25: blink = (num == 5); break;
|
||||
case 7: case 27: inverse = (num == 7); break;
|
||||
case 8: case 28: invisible = (num == 8); break;
|
||||
case 1: case 22: set_attribute(bold, value); break;
|
||||
case 3: case 23: set_attribute(italic, value); break;
|
||||
case 4: case 24: set_attribute(underlined, value); break;
|
||||
case 5: case 25: set_attribute(blink, value); break;
|
||||
case 7: case 27: set_attribute(inverse, value); break;
|
||||
case 8: case 28: set_attribute(invisible, value); break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,12 +510,12 @@ std::string Renditions::sgr( void ) const
|
||||
std::string ret;
|
||||
|
||||
ret.append( "\033[0" );
|
||||
if ( bold ) ret.append( ";1" );
|
||||
if ( italic ) ret.append( ";3" );
|
||||
if ( underlined ) ret.append( ";4" );
|
||||
if ( blink ) ret.append( ";5" );
|
||||
if ( inverse ) ret.append( ";7" );
|
||||
if ( invisible ) ret.append( ";8" );
|
||||
if ( get_attribute( bold ) ) ret.append( ";1" );
|
||||
if ( get_attribute( italic ) ) ret.append( ";3" );
|
||||
if ( get_attribute( underlined ) ) ret.append( ";4" );
|
||||
if ( get_attribute( blink ) ) ret.append( ";5" );
|
||||
if ( get_attribute( inverse ) ) ret.append( ";7" );
|
||||
if ( get_attribute( invisible ) ) ret.append( ";8" );
|
||||
|
||||
if ( foreground_color
|
||||
&& (foreground_color <= 37) ) {
|
||||
@@ -570,7 +602,7 @@ void Renditions::posterize( void )
|
||||
}
|
||||
}
|
||||
|
||||
void Row::reset( int background_color )
|
||||
void Row::reset( color_type background_color )
|
||||
{
|
||||
for ( cells_type::iterator i = cells.begin();
|
||||
i != cells.end();
|
||||
@@ -579,22 +611,13 @@ void Row::reset( int background_color )
|
||||
}
|
||||
}
|
||||
|
||||
void Framebuffer::prefix_window_title( const std::deque<wchar_t> &s )
|
||||
void Framebuffer::prefix_window_title( const title_type &s )
|
||||
{
|
||||
if ( icon_name == window_title ) {
|
||||
/* preserve equivalence */
|
||||
for ( std::deque<wchar_t>::const_reverse_iterator i = s.rbegin();
|
||||
i != s.rend();
|
||||
i++ ) {
|
||||
icon_name.push_front( *i );
|
||||
}
|
||||
}
|
||||
|
||||
for ( std::deque<wchar_t>::const_reverse_iterator i = s.rbegin();
|
||||
i != s.rend();
|
||||
i++ ) {
|
||||
window_title.push_front( *i );
|
||||
icon_name.insert(icon_name.begin(), s.begin(), s.end() );
|
||||
}
|
||||
window_title.insert(window_title.begin(), s.begin(), s.end() );
|
||||
}
|
||||
|
||||
wint_t Cell::debug_contents( void ) const
|
||||
@@ -602,7 +625,11 @@ wint_t Cell::debug_contents( void ) const
|
||||
if ( contents.empty() ) {
|
||||
return '_';
|
||||
} else {
|
||||
return contents.front();
|
||||
/* very, very cheesy */
|
||||
wchar_t ch[2];
|
||||
const std::string chars( contents.begin(), contents.end() );
|
||||
mbstowcs(ch, chars.c_str(), 1);
|
||||
return ch[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,65 +33,68 @@
|
||||
#ifndef TERMINALFB_HPP
|
||||
#define TERMINALFB_HPP
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <assert.h>
|
||||
|
||||
/* Terminal framebuffer */
|
||||
|
||||
namespace Terminal {
|
||||
typedef uint16_t color_type;
|
||||
|
||||
class Renditions {
|
||||
public:
|
||||
bool bold, italic, underlined, blink, inverse, invisible;
|
||||
int foreground_color;
|
||||
int background_color;
|
||||
typedef enum { bold, faint, italic, underlined, blink, inverse, invisible, SIZE } attribute_type;
|
||||
|
||||
Renditions( int s_background );
|
||||
// all together, a 32 bit word now...
|
||||
unsigned int foreground_color : 12;
|
||||
unsigned int background_color : 12;
|
||||
private:
|
||||
unsigned int attributes : 8;
|
||||
|
||||
public:
|
||||
Renditions( color_type s_background );
|
||||
void set_foreground_color( int num );
|
||||
void set_background_color( int num );
|
||||
void set_rendition( int num );
|
||||
void set_rendition( color_type num );
|
||||
std::string sgr( void ) const;
|
||||
|
||||
void posterize( void );
|
||||
|
||||
bool operator==( const Renditions &x ) const
|
||||
{
|
||||
return (bold == x.bold) && (italic == x.italic) && (underlined == x.underlined)
|
||||
&& (blink == x.blink) && (inverse == x.inverse)
|
||||
&& (invisible == x.invisible) && (foreground_color == x.foreground_color)
|
||||
&& (background_color == x.background_color);
|
||||
return ( attributes == x.attributes )
|
||||
&& ( foreground_color == x.foreground_color )
|
||||
&& ( background_color == x.background_color );
|
||||
}
|
||||
void set_attribute( attribute_type attr, bool val )
|
||||
{
|
||||
attributes = val ?
|
||||
( attributes | (1 << attr) ) :
|
||||
( attributes & ~(1 << attr) );
|
||||
}
|
||||
bool get_attribute( attribute_type attr ) const { return attributes & ( 1 << attr ); }
|
||||
void clear_attributes() { attributes = 0; }
|
||||
};
|
||||
|
||||
class Cell {
|
||||
public:
|
||||
std::vector<wchar_t> contents;
|
||||
char fallback; /* first character is combining character */
|
||||
int width;
|
||||
typedef std::string content_type; /* can be std::string, std::vector<uint8_t>, or __gnu_cxx::__vstring */
|
||||
content_type contents;
|
||||
Renditions renditions;
|
||||
uint8_t width;
|
||||
bool fallback; /* first character is combining character */
|
||||
bool wrap; /* if last cell, wrap to next line */
|
||||
|
||||
Cell( int background_color )
|
||||
: contents(),
|
||||
fallback( false ),
|
||||
width( 1 ),
|
||||
renditions( background_color ),
|
||||
wrap( false )
|
||||
{}
|
||||
Cell( color_type background_color );
|
||||
Cell(); /* default constructor required by C++11 STL */
|
||||
|
||||
Cell() /* default constructor required by C++11 STL */
|
||||
: contents(),
|
||||
fallback( false ),
|
||||
width( 1 ),
|
||||
renditions( 0 ),
|
||||
wrap( false )
|
||||
{
|
||||
assert( false );
|
||||
}
|
||||
|
||||
void reset( int background_color );
|
||||
void reset( color_type background_color );
|
||||
|
||||
bool operator==( const Cell &x ) const
|
||||
{
|
||||
@@ -102,13 +105,15 @@ namespace Terminal {
|
||||
&& (wrap == x.wrap) );
|
||||
}
|
||||
|
||||
bool operator!=( const Cell &x ) const { return !operator==( x ); }
|
||||
|
||||
wint_t debug_contents( void ) const;
|
||||
|
||||
bool is_blank( void ) const
|
||||
{
|
||||
return ( contents.empty()
|
||||
|| ( (contents.size() == 1) && ( (contents.front() == 0x20)
|
||||
|| (contents.front() == 0xA0) ) ) );
|
||||
|| contents == " "
|
||||
|| contents == "\xC2\xA0" );
|
||||
}
|
||||
|
||||
bool contents_match ( const Cell &other ) const
|
||||
@@ -118,6 +123,26 @@ namespace Terminal {
|
||||
}
|
||||
|
||||
bool compare( const Cell &other ) const;
|
||||
|
||||
static void append_to_str( std::string &dest, const wchar_t c )
|
||||
{
|
||||
static mbstate_t ps = mbstate_t();
|
||||
char tmp[MB_LEN_MAX];
|
||||
size_t ignore = wcrtomb(NULL, 0, &ps);
|
||||
(void)ignore;
|
||||
size_t len = wcrtomb(tmp, c, &ps);
|
||||
dest.append( tmp, len );
|
||||
}
|
||||
|
||||
void append( const wchar_t c )
|
||||
{
|
||||
static mbstate_t ps = mbstate_t();
|
||||
char tmp[MB_LEN_MAX];
|
||||
size_t ignore = wcrtomb(NULL, 0, &ps);
|
||||
(void)ignore;
|
||||
size_t len = wcrtomb(tmp, c, &ps);
|
||||
contents.insert( contents.end(), tmp, tmp+len );
|
||||
}
|
||||
};
|
||||
|
||||
class Row {
|
||||
@@ -125,20 +150,13 @@ namespace Terminal {
|
||||
typedef std::vector<Cell> cells_type;
|
||||
cells_type cells;
|
||||
|
||||
Row( size_t s_width, int background_color )
|
||||
: cells( s_width, Cell( background_color ) )
|
||||
{}
|
||||
Row( size_t s_width, color_type background_color );
|
||||
Row(); /* default constructor required by C++11 STL */
|
||||
|
||||
Row() /* default constructor required by C++11 STL */
|
||||
: cells( 1, Cell() )
|
||||
{
|
||||
assert( false );
|
||||
}
|
||||
void insert_cell( int col, color_type background_color );
|
||||
void delete_cell( int col, color_type background_color );
|
||||
|
||||
void insert_cell( int col, int background_color );
|
||||
void delete_cell( int col, int background_color );
|
||||
|
||||
void reset( int background_color );
|
||||
void reset( color_type background_color );
|
||||
|
||||
bool operator==( const Row &x ) const
|
||||
{
|
||||
@@ -240,7 +258,7 @@ namespace Terminal {
|
||||
|
||||
void set_foreground_color( int x ) { renditions.set_foreground_color( x ); }
|
||||
void set_background_color( int x ) { renditions.set_background_color( x ); }
|
||||
void add_rendition( int x ) { renditions.set_rendition( x ); }
|
||||
void add_rendition( color_type x ) { renditions.set_rendition( x ); }
|
||||
Renditions get_renditions( void ) const { return renditions; }
|
||||
int get_background_rendition( void ) const { return renditions.background_color; }
|
||||
|
||||
@@ -265,11 +283,14 @@ namespace Terminal {
|
||||
};
|
||||
|
||||
class Framebuffer {
|
||||
public:
|
||||
typedef std::vector<wchar_t> title_type;
|
||||
|
||||
private:
|
||||
typedef std::deque<Row> rows_type;
|
||||
typedef std::vector<Row> rows_type;
|
||||
rows_type rows;
|
||||
std::deque<wchar_t> icon_name;
|
||||
std::deque<wchar_t> window_title;
|
||||
title_type icon_name;
|
||||
title_type window_title;
|
||||
unsigned int bell_count;
|
||||
bool title_initialized; /* true if the window title has been set via an OSC */
|
||||
|
||||
@@ -289,12 +310,7 @@ namespace Terminal {
|
||||
return &rows[ row ];
|
||||
}
|
||||
|
||||
inline const Cell *get_cell( void ) const
|
||||
{
|
||||
return &rows[ ds.get_cursor_row() ].cells[ ds.get_cursor_col() ];
|
||||
}
|
||||
|
||||
inline const Cell *get_cell( int row, int col ) const
|
||||
inline const Cell *get_cell( int row = -1, int col = -1 ) const
|
||||
{
|
||||
if ( row == -1 ) row = ds.get_cursor_row();
|
||||
if ( col == -1 ) col = ds.get_cursor_col();
|
||||
@@ -304,22 +320,12 @@ namespace Terminal {
|
||||
|
||||
Row *get_mutable_row( int row )
|
||||
{
|
||||
if ( row == -1 ) row = ds.get_cursor_row();
|
||||
|
||||
return &rows[ row ];
|
||||
return const_cast<Row *>(get_row( row ));
|
||||
}
|
||||
|
||||
inline Cell *get_mutable_cell( void )
|
||||
inline Cell *get_mutable_cell( int row = -1, int col = -1 )
|
||||
{
|
||||
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 const_cast<Cell *>(get_cell( row, col ));
|
||||
}
|
||||
|
||||
Cell *get_combining_cell( void );
|
||||
@@ -337,12 +343,12 @@ namespace Terminal {
|
||||
|
||||
void set_title_initialized( void ) { title_initialized = true; }
|
||||
bool is_title_initialized( void ) const { return title_initialized; }
|
||||
void set_icon_name( const std::deque<wchar_t> &s ) { icon_name = s; }
|
||||
void set_window_title( const std::deque<wchar_t> &s ) { window_title = s; }
|
||||
const std::deque<wchar_t> & get_icon_name( void ) const { return icon_name; }
|
||||
const std::deque<wchar_t> & get_window_title( void ) const { return window_title; }
|
||||
void set_icon_name( const title_type &s ) { icon_name = s; }
|
||||
void set_window_title( const title_type &s ) { window_title = s; }
|
||||
const title_type & get_icon_name( void ) const { return icon_name; }
|
||||
const title_type & get_window_title( void ) const { return window_title; }
|
||||
|
||||
void prefix_window_title( const std::deque<wchar_t> &s );
|
||||
void prefix_window_title( const title_type &s );
|
||||
|
||||
void resize( int s_width, int s_height );
|
||||
|
||||
|
||||
@@ -559,7 +559,7 @@ void Dispatcher::OSC_dispatch( const Parser::OSC_End *act, Framebuffer *fb )
|
||||
bool set_title = (cmd_num == 0 || cmd_num == 2);
|
||||
if ( set_icon || set_title ) {
|
||||
fb->set_title_initialized();
|
||||
std::deque<wchar_t> newtitle( OSC_string.begin() + offset, OSC_string.end() );
|
||||
Terminal::Framebuffer::title_type newtitle( OSC_string.begin() + offset, OSC_string.end() );
|
||||
if ( set_icon ) { fb->set_icon_name( newtitle ); }
|
||||
if ( set_title ) { fb->set_window_title( newtitle ); }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user