Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/terminal/terminaldisplay.cc
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ std::string Display::new_frame( bool initialized, const Framebuffer& last, const
frame.append( tmp );
}

if ( f.ds.cursor_shape != frame.last_frame.ds.cursor_shape && f.ds.cursor_shape != -1 ) {
snprintf(tmp, sizeof(tmp), "\033[%d q", f.ds.cursor_shape);
frame.append(tmp);
}

/* has size changed? */
if ( ( !initialized ) || ( f.ds.get_width() != frame.last_frame.ds.get_width() )
|| ( f.ds.get_height() != frame.last_frame.ds.get_height() ) ) {
Expand Down
6 changes: 3 additions & 3 deletions src/terminal/terminalframebuffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ DrawState::DrawState( int s_width, int s_height )
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 ),
application_mode_cursor_keys( false )
reverse_video( false ), bracketed_paste( false ), cursor_shape( -1 ),
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 );
}
Expand Down
11 changes: 10 additions & 1 deletion src/terminal/terminalframebuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,8 @@ class SavedCursor
class DrawState
{
private:
static const int cursor_shape_count = 7; /* 0-6 are valid cursor control code */

int width, height;

void new_grapheme( void );
Expand Down Expand Up @@ -282,6 +284,7 @@ class DrawState
bool cursor_visible;
bool reverse_video;
bool bracketed_paste;
int cursor_shape;

enum MouseReportingMode
{
Expand Down Expand Up @@ -317,6 +320,12 @@ class DrawState
int get_combining_char_row( void ) const { return combining_char_row; }
int get_width( void ) const { return width; }
int get_height( void ) const { return height; }
void set_cursor_shape(int shape)
{
if ( shape >= 0 && shape < cursor_shape_count ) {
cursor_shape = shape;
}
}

void set_tab( void );
void clear_tab( int col );
Expand Down Expand Up @@ -355,7 +364,7 @@ class DrawState
&& ( 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 )
&& ( mouse_encoding_mode == x.mouse_encoding_mode );
&& ( mouse_encoding_mode == x.mouse_encoding_mode ) && (cursor_shape == x.cursor_shape);
}
};

Expand Down
11 changes: 11 additions & 0 deletions src/terminal/terminalfunctions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,17 @@ static Function func_CSI_cursormove_D( CSI, "D", CSI_cursormove );
static Function func_CSI_cursormove_H( CSI, "H", CSI_cursormove );
static Function func_CSI_cursormove_f( CSI, "f", CSI_cursormove );

/* cursor shape */
static void CSI_cursorshape( Framebuffer* fb, Dispatcher* dispatch )
{
int shape = dispatch->getparam( 0, -1 );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm looking at the impl for Dispather::getparam and it looks like doesn't support returning values less than 1. But 0 is a valid cursor shape.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. The defaultval should be 0.


fb->ds.set_cursor_shape(shape);
}

static Function func_CSI_cursorshape( CSI, " q", CSI_cursorshape );


/* device attributes */
static void CSI_DA( Framebuffer* fb __attribute( ( unused ) ), Dispatcher* dispatch )
{
Expand Down
44 changes: 44 additions & 0 deletions src/tests/emulation-cursor-shape.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/bin/sh

#
# This test exercises the cursor shape ascii sequence in Mosh.
#

# shellcheck source=e2e-test-subrs
. "$(dirname "$0")/e2e-test-subrs"
PATH=$PATH:.:$srcdir
# Top-level wrapper.
if [ $# -eq 0 ]; then
e2e-test "$0" baseline direct verify
exit
fi

# OK, we have arguments, we're one of the test hooks.
if [ $# -ne 1 ]; then
fail "bad arguments %s\n" "$@"
fi

baseline()
{
while read -r shape sleep_time text; do
printf '\n\033[%d q%s' "$shape" "$text"
sleep $sleep_time
done <<EOF
0 1 Block
1 1 Block
2 2 BlinkBlock
3 1 Underline
4 2 BlinkUnderline
5 1 Bar
6 2 BlinkBar
0 0 done
EOF
echo
}

case $1 in
baseline|direct)
baseline;;
*)
fail "unknown test argument %s\n" "$1";;
esac