From cfd279fa2583f33a3e575cda226727b5c9bc8b06 Mon Sep 17 00:00:00 2001 From: Keith Winstein Date: Sat, 22 Jan 2011 04:58:01 -0500 Subject: [PATCH] Support wide characters and combining characters --- termemu.cpp | 5 ----- terminal.cpp | 39 ++++++++++++++++++++++++++++++++++----- terminal.hpp | 2 ++ terminalcsi.cpp | 2 +- 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/termemu.cpp b/termemu.cpp index a5af174..5f65d0b 100644 --- a/termemu.cpp +++ b/termemu.cpp @@ -64,11 +64,6 @@ int main( int argc __attribute__((unused)), if ( child == 0 ) { /* child */ - if ( chdir( "/" ) < 0 ) { - perror( "chdir" ); - exit( 1 ); - } - char *my_argv[ 2 ]; my_argv[ 0 ] = strdup( "/bin/bash" ); assert( my_argv[ 0 ] ); diff --git a/terminal.cpp b/terminal.cpp index eabbd4c..5b7c942 100644 --- a/terminal.cpp +++ b/terminal.cpp @@ -38,7 +38,7 @@ Emulator::Emulator( size_t s_width, size_t s_height ) cursor_col( 0 ), cursor_row( 0 ), combining_char_col( 0 ), combining_char_row( 0 ), rows( height, Row( width ) ), - params(), dispatch_chars(), parsed_params() + params(), dispatch_chars(), errors(), parsed_params() { } @@ -126,6 +126,8 @@ void Emulator::print( Parser::Print *act ) int chwidth = act->ch == L'\0' ? -1 : wcwidth( act->ch ); + Cell *this_cell; + switch ( chwidth ) { case 1: /* normal character */ case 2: /* wide character */ @@ -136,13 +138,39 @@ void Emulator::print( Parser::Print *act ) autoscroll(); - rows[ cursor_row ].cells[ cursor_col ].contents.clear(); - rows[ cursor_row ].cells[ cursor_col ].contents.push_back( act->ch ); + this_cell = &rows[ cursor_row ].cells[ cursor_col ]; + this_cell->contents.clear(); + this_cell->contents.push_back( act->ch ); + for ( std::vector::iterator i + = this_cell->overlapped_cells.begin(); + i != this_cell->overlapped_cells.end(); + i++ ) { + **i = Cell(); + } + this_cell->overlapped_cells.clear(); + newgrapheme(); - cursor_col++; + + if ( cursor_col < width - 1 ) { + Cell *next_cell = &rows[ cursor_row ].cells[ cursor_col + 1 ]; + if ( chwidth == 2 ) { + this_cell->overlapped_cells.push_back( next_cell ); + next_cell->overlapping_cell = this_cell; + } else { + next_cell->overlapping_cell = NULL; + } + } + + cursor_col += chwidth; + break; + case 0: /* combining character */ + if ( rows[ combining_char_row ].cells[ combining_char_col ].contents.size() < 16 ) { /* seems like a reasonable limit on combining character */ + rows[ combining_char_row ].cells[ combining_char_col ].contents.push_back( act->ch ); + } + case -1: /* unprintable character */ break; default: - break; + assert( false ); } } @@ -154,6 +182,7 @@ void Emulator::debug_printout( FILE *f ) for ( int x = 0; x < width; x++ ) { fprintf( f, "\033[%d;%dH", y + 1, x + 1 ); Cell *cell = &rows[ y ].cells[ x ]; + if ( cell->overlapping_cell ) continue; for ( std::vector::iterator i = cell->contents.begin(); i != cell->contents.end(); i++ ) { diff --git a/terminal.hpp b/terminal.hpp index 7ef0e52..de37ce1 100644 --- a/terminal.hpp +++ b/terminal.hpp @@ -46,6 +46,8 @@ namespace Terminal { std::string params; std::string dispatch_chars; + std::string errors; + /* action methods */ void print( Parser::Print *act ); void execute( Parser::Execute *act ); diff --git a/terminalcsi.cpp b/terminalcsi.cpp index 1fa06cb..5215e22 100644 --- a/terminalcsi.cpp +++ b/terminalcsi.cpp @@ -45,7 +45,7 @@ void Emulator::CSI_cursormove( void ) if ( cursor_row < 0 ) cursor_row = 0; if ( cursor_row >= height ) cursor_row = height - 1; if ( cursor_col < 0 ) cursor_col = 0; - if ( cursor_col >= width ) cursor_col = width; + if ( cursor_col >= width ) cursor_col = width - 1; newgrapheme(); }