From c7740d43fe616889aa89ac82a1dd631ef54193b5 Mon Sep 17 00:00:00 2001 From: matheusfillipe Date: Sat, 11 Dec 2021 17:49:09 -0300 Subject: [PATCH] Improve cursor style handling --- src/terminal/terminaldisplay.cc | 15 +++++++++++++++ src/terminal/terminaldisplay.h | 1 + src/terminal/terminalframebuffer.cc | 2 ++ src/terminal/terminalframebuffer.h | 13 +++++++++++++ src/terminal/terminalfunctions.cc | 20 ++++++++++++++++++++ 5 files changed, 51 insertions(+) diff --git a/src/terminal/terminaldisplay.cc b/src/terminal/terminaldisplay.cc index e7595c248..903407208 100644 --- a/src/terminal/terminaldisplay.cc +++ b/src/terminal/terminaldisplay.cc @@ -154,6 +154,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() ); @@ -286,6 +292,14 @@ 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 ); @@ -483,6 +497,7 @@ bool Display::put_row( bool initialized, FrameState &frame, const Framebuffer &f FrameState::FrameState( const Framebuffer &s_last ) : str(), cursor_x(0), cursor_y(0), current_rendition( 0 ), cursor_visible( s_last.ds.cursor_visible ), + cursor_style( s_last.ds.cursor_style ), last_frame( s_last ) { /* Preallocate for better performance. Make a guess-- doesn't matter for correctness */ diff --git a/src/terminal/terminaldisplay.h b/src/terminal/terminaldisplay.h index 81009b014..0d6335d43 100644 --- a/src/terminal/terminaldisplay.h +++ b/src/terminal/terminaldisplay.h @@ -44,6 +44,7 @@ namespace Terminal { 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 2751f3b7d..7b7d076c9 100644 --- a/src/terminal/terminalframebuffer.cc +++ b/src/terminal/terminalframebuffer.cc @@ -69,6 +69,7 @@ DrawState::DrawState( int s_width, int s_height ) 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(), + 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 ), @@ -392,6 +393,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 de9386977..4c2345be5 100644 --- a/src/terminal/terminalframebuffer.h +++ b/src/terminal/terminalframebuffer.h @@ -51,6 +51,16 @@ namespace Terminal { using shared::make_shared; typedef uint32_t color_type; + 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: typedef enum { bold, faint, italic, underlined, blink, inverse, invisible, SIZE } attribute_type; @@ -275,6 +285,8 @@ namespace Terminal { SavedCursor save; public: + int cursor_style; + bool next_print_will_wrap; bool origin_mode; bool auto_wrap_mode; @@ -351,6 +363,7 @@ namespace Terminal { 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 ) && + ( 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 ca141dd35..7cf6e58f2 100644 --- a/src/terminal/terminalfunctions.cc +++ b/src/terminal/terminalfunctions.cc @@ -50,6 +50,26 @@ 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 ) {