diff --git a/src/terminal/terminaldisplay.cc b/src/terminal/terminaldisplay.cc index c44952857..b3af91b72 100644 --- a/src/terminal/terminaldisplay.cc +++ b/src/terminal/terminaldisplay.cc @@ -142,6 +142,12 @@ std::string Display::new_frame( bool initialized, const Framebuffer& last, const frame.append( "\033[?25l" ); } + /* is cursor style initialized? */ + if ( !initialized ) { + frame.cursor_style = Terminal::CursorStyle::BLINKING_BLOCK; + frame.append( "\033[0 q" ); + } + int frame_y = 0; Framebuffer::row_pointer blank_row; Framebuffer::rows_type rows( frame.last_frame.get_rows() ); @@ -267,6 +273,13 @@ std::string Display::new_frame( bool initialized, const Framebuffer& last, const } } + /* has cursor style changed? */ + if ( ( !initialized ) || ( f.ds.cursor_style != frame.cursor_style ) ) { + char cursor_style_sequence_buf[6]; + snprintf( cursor_style_sequence_buf, sizeof cursor_style_sequence_buf, "\033[%d q", f.ds.cursor_style ); + frame.append( cursor_style_sequence_buf ); + } + /* have renditions changed? */ frame.update_rendition( f.ds.get_renditions(), !initialized ); @@ -460,7 +473,7 @@ bool Display::put_row( bool initialized, FrameState::FrameState( const Framebuffer& s_last ) : str(), cursor_x( 0 ), cursor_y( 0 ), current_rendition( 0 ), cursor_visible( s_last.ds.cursor_visible ), - last_frame( s_last ) + cursor_style( s_last.ds.cursor_style ), last_frame( s_last ) { /* Preallocate for better performance. Make a guess-- doesn't matter for correctness */ str.reserve( last_frame.ds.get_width() * last_frame.ds.get_height() * 4 ); diff --git a/src/terminal/terminaldisplay.h b/src/terminal/terminaldisplay.h index bd900e8fa..3378b848c 100644 --- a/src/terminal/terminaldisplay.h +++ b/src/terminal/terminaldisplay.h @@ -45,6 +45,7 @@ class FrameState int cursor_x, cursor_y; Renditions current_rendition; bool cursor_visible; + int cursor_style; const Framebuffer& last_frame; diff --git a/src/terminal/terminalframebuffer.cc b/src/terminal/terminalframebuffer.cc index 5d3a1bc07..06bb6f1d9 100644 --- a/src/terminal/terminalframebuffer.cc +++ b/src/terminal/terminalframebuffer.cc @@ -62,10 +62,11 @@ void DrawState::reinitialize_tabs( unsigned int start ) DrawState::DrawState( int s_width, int s_height ) : width( s_width ), height( s_height ), cursor_col( 0 ), cursor_row( 0 ), combining_char_col( 0 ), combining_char_row( 0 ), default_tabs( true ), tabs( s_width ), scrolling_region_top_row( 0 ), - scrolling_region_bottom_row( height - 1 ), renditions( 0 ), save(), next_print_will_wrap( false ), - origin_mode( false ), auto_wrap_mode( true ), insert_mode( false ), cursor_visible( true ), - reverse_video( false ), bracketed_paste( false ), mouse_reporting_mode( MOUSE_REPORTING_NONE ), - mouse_focus_event( false ), mouse_alternate_scroll( false ), mouse_encoding_mode( MOUSE_ENCODING_DEFAULT ), + scrolling_region_bottom_row( height - 1 ), renditions( 0 ), save(), + cursor_style( Terminal::CursorStyle::BLINKING_BLOCK ), next_print_will_wrap( false ), origin_mode( false ), + auto_wrap_mode( true ), insert_mode( false ), cursor_visible( true ), reverse_video( false ), + bracketed_paste( false ), mouse_reporting_mode( MOUSE_REPORTING_NONE ), mouse_focus_event( false ), + mouse_alternate_scroll( false ), mouse_encoding_mode( MOUSE_ENCODING_DEFAULT ), application_mode_cursor_keys( false ) { reinitialize_tabs( 0 ); @@ -387,6 +388,7 @@ void Framebuffer::soft_reset( void ) ds.insert_mode = false; ds.origin_mode = false; ds.cursor_visible = true; /* per xterm and gnome-terminal */ + ds.cursor_style = Terminal::CursorStyle::BLINKING_BLOCK; ds.application_mode_cursor_keys = false; ds.set_scrolling_region( 0, ds.get_height() - 1 ); ds.add_rendition( 0 ); diff --git a/src/terminal/terminalframebuffer.h b/src/terminal/terminalframebuffer.h index 9039d4e7f..5000ff651 100644 --- a/src/terminal/terminalframebuffer.h +++ b/src/terminal/terminalframebuffer.h @@ -45,8 +45,21 @@ /* Terminal framebuffer */ namespace Terminal { +using std::make_shared; +using std::shared_ptr; using color_type = uint32_t; +enum CursorStyle +{ + BLINKING_BLOCK = 0, + BLINKING_BLOCK_DEFAULT = 1, + STEADY_BLOCK = 2, + BLINKING_UNDERLINE = 3, + STEADY_UNDERLINE = 4, + BLINKING_BAR = 5, + STEADY_BAR = 6, +}; + class Renditions { public: @@ -275,6 +288,7 @@ class DrawState SavedCursor save; public: + int cursor_style; bool next_print_will_wrap; bool origin_mode; bool auto_wrap_mode; @@ -353,8 +367,9 @@ class DrawState return ( width == x.width ) && ( height == x.height ) && ( cursor_col == x.cursor_col ) && ( cursor_row == x.cursor_row ) && ( cursor_visible == x.cursor_visible ) && ( reverse_video == x.reverse_video ) && ( renditions == x.renditions ) - && ( bracketed_paste == x.bracketed_paste ) && ( mouse_reporting_mode == x.mouse_reporting_mode ) - && ( mouse_focus_event == x.mouse_focus_event ) && ( mouse_alternate_scroll == x.mouse_alternate_scroll ) + && ( cursor_style == x.cursor_style ) && ( bracketed_paste == x.bracketed_paste ) + && ( mouse_reporting_mode == x.mouse_reporting_mode ) && ( mouse_focus_event == x.mouse_focus_event ) + && ( mouse_alternate_scroll == x.mouse_alternate_scroll ) && ( mouse_encoding_mode == x.mouse_encoding_mode ); } }; diff --git a/src/terminal/terminalfunctions.cc b/src/terminal/terminalfunctions.cc index 40c41afc4..000b4d401 100644 --- a/src/terminal/terminalfunctions.cc +++ b/src/terminal/terminalfunctions.cc @@ -51,6 +51,27 @@ static void clearline( Framebuffer* fb, int row, int start, int end ) } } +/* cursor style */ +static void CSI_DECSCUSR( Framebuffer* fb, Dispatcher* dispatch ) +{ + int style = dispatch->getparam( 0, 0 ); + switch ( style ) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + fb->ds.cursor_style = style; + break; + default: + break; + } +} + +static Function func_CSI_DECSCUSR( CSI, " q", CSI_DECSCUSR ); + /* erase in line */ static void CSI_EL( Framebuffer* fb, Dispatcher* dispatch ) {