From c4236c6762d02a76ed74527d2f10ee0991247fea Mon Sep 17 00:00:00 2001 From: Louis Kruger Date: Sun, 28 Dec 2014 22:09:12 -0800 Subject: [PATCH] Fix xterm mouse support. --- src/terminal/terminaldisplay.cc | 46 ++++++++++++++++++++--------- src/terminal/terminalframebuffer.cc | 4 +-- src/terminal/terminalframebuffer.h | 29 +++++++++++++----- src/terminal/terminalfunctions.cc | 38 +++++++++++------------- 4 files changed, 74 insertions(+), 43 deletions(-) diff --git a/src/terminal/terminaldisplay.cc b/src/terminal/terminaldisplay.cc index 70d698c..cad8da5 100644 --- a/src/terminal/terminaldisplay.cc +++ b/src/terminal/terminaldisplay.cc @@ -292,27 +292,45 @@ std::string Display::new_frame( bool initialized, const Framebuffer &last, const frame.append( f.ds.bracketed_paste ? "\033[?2004h" : "\033[?2004l" ); } - /* has xterm VT100 mouse mode changed? */ + /* has mouse reporting mode changed? */ if ( (!initialized) - || (f.ds.vt100_mouse != frame.last_frame.ds.vt100_mouse) ) { - frame.append( f.ds.vt100_mouse ? "\033[?1000h" : "\033[?1000l" ); + || (f.ds.mouse_reporting_mode != frame.last_frame.ds.mouse_reporting_mode) ) { + if (f.ds.mouse_reporting_mode == DrawState::MOUSE_REPORTING_NONE) { + frame.append("\033[?1003l"); + frame.append("\033[?1002l"); + frame.append("\033[?1001l"); + frame.append("\033[?1000l"); + } else { + if (frame.last_frame.ds.mouse_reporting_mode != DrawState::MOUSE_REPORTING_NONE) { + snprintf(tmp, sizeof(tmp), "\033[?%dl", frame.last_frame.ds.mouse_reporting_mode); + frame.append(tmp); + } + snprintf(tmp, sizeof(tmp), "\033[?%dh", f.ds.mouse_reporting_mode); + frame.append(tmp); + } } - /* has xterm mouse mode changed? */ + /* has mouse focus mode changed? */ if ( (!initialized) - || (f.ds.xterm_mouse != frame.last_frame.ds.xterm_mouse) ) { - frame.append( f.ds.xterm_mouse ? "\033[?1002h" : "\033[?1002l" ); + || (f.ds.mouse_focus_event != frame.last_frame.ds.mouse_focus_event) ) { + frame.append( f.ds.mouse_focus_event ? "\033[?1004h" : "\033[?1004l" ); } - /* has xterm mouse mode changed? */ + /* has mouse encoding mode changed? */ if ( (!initialized) - || (f.ds.xterm_extended_mouse != frame.last_frame.ds.xterm_extended_mouse) ) { - frame.append( f.ds.xterm_extended_mouse ? "\033[?1006h" : "\033[?1006l" ); - } - - if ( (!initialized) - || (f.ds.xterm_utf8_mouse != frame.last_frame.ds.xterm_utf8_mouse) ) { - frame.append( f.ds.xterm_utf8_mouse ? "\033[?1005h" : "\033[?1005l" ); + || (f.ds.mouse_encoding_mode != frame.last_frame.ds.mouse_encoding_mode) ) { + if (f.ds.mouse_encoding_mode == DrawState::MOUSE_ENCODING_DEFAULT) { + frame.append("\033[?1015l"); + frame.append("\033[?1006l"); + frame.append("\033[?1005l"); + } else { + if (frame.last_frame.ds.mouse_encoding_mode != DrawState::MOUSE_ENCODING_DEFAULT) { + snprintf(tmp, sizeof(tmp), "\033[?%dl", frame.last_frame.ds.mouse_encoding_mode); + frame.append(tmp); + } + snprintf(tmp, sizeof(tmp), "\033[?%dh", f.ds.mouse_encoding_mode); + frame.append(tmp); + } } return frame.str; diff --git a/src/terminal/terminalframebuffer.cc b/src/terminal/terminalframebuffer.cc index 43bd6b4..3ab753d 100644 --- a/src/terminal/terminalframebuffer.cc +++ b/src/terminal/terminalframebuffer.cc @@ -62,8 +62,8 @@ DrawState::DrawState( int s_width, int s_height ) 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 ), vt100_mouse( false ), xterm_mouse( false ), - xterm_extended_mouse( false ), xterm_utf8_mouse( false ), application_mode_cursor_keys( 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 ); } diff --git a/src/terminal/terminalframebuffer.h b/src/terminal/terminalframebuffer.h index 97fd355..836aa84 100644 --- a/src/terminal/terminalframebuffer.h +++ b/src/terminal/terminalframebuffer.h @@ -190,10 +190,25 @@ namespace Terminal { bool cursor_visible; bool reverse_video; bool bracketed_paste; - bool vt100_mouse; - bool xterm_mouse; - bool xterm_extended_mouse; // aka SGR - bool xterm_utf8_mouse; + + enum MouseReportingMode { + MOUSE_REPORTING_NONE = 0, + MOUSE_REPORTING_X10 = 9, + MOUSE_REPORTING_VT220 = 1000, + MOUSE_REPORTING_VT220_HILIGHT = 1001, + MOUSE_REPORTING_BTN_EVENT = 1002, + MOUSE_REPORTING_ANY_EVENT = 1003, + } mouse_reporting_mode; + + bool mouse_focus_event; // 1004 + bool mouse_alternate_scroll; // 1007 + + enum MouseEncodingMode { + MOUSE_ENCODING_DEFAULT = 0, + MOUSE_ENCODING_UTF8 = 1005, + MOUSE_ENCODING_SGR = 1006, + MOUSE_ENCODING_URXVT = 1015, + } mouse_encoding_mode; bool application_mode_cursor_keys; @@ -243,9 +258,9 @@ 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 ) && - ( bracketed_paste == x.bracketed_paste ) && ( vt100_mouse == x.vt100_mouse ) && - ( xterm_mouse == x.xterm_mouse ) && ( xterm_extended_mouse == x.xterm_extended_mouse ) && - ( xterm_utf8_mouse == x.xterm_utf8_mouse ); + ( 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 a1902a8..547e00a 100644 --- a/src/terminal/terminalfunctions.cc +++ b/src/terminal/terminalfunctions.cc @@ -268,14 +268,10 @@ static bool *get_DEC_mode( int param, Framebuffer *fb ) { return &(fb->ds.auto_wrap_mode); case 25: return &(fb->ds.cursor_visible); - case 1000: /* xterm mouse 1 (normal) */ - return &(fb->ds.vt100_mouse); - case 1002: /* xterm mouse 2 (inc. button drags) */ - return &(fb->ds.xterm_mouse); - case 1005: /* xterm UTF8 mouse */ - return &(fb->ds.xterm_utf8_mouse); - case 1006: /* xterm extended mouse */ - return &(fb->ds.xterm_extended_mouse); + case 1004: /* xterm mouse focus event */ + return &(fb->ds.mouse_focus_event); + case 1007: /* xterm mouse alternate scroll */ + return &(fb->ds.mouse_alternate_scroll); case 2004: /* bracketed paste */ return &(fb->ds.bracketed_paste); } @@ -293,18 +289,13 @@ void CSI_DECSM( Framebuffer *fb, Dispatcher *dispatch ) { for ( int i = 0; i < dispatch->param_count(); i++ ) { int param = dispatch->getparam( i, 0 ); - - if ( (param == 1000) || (param == 1002) ) { - /* we believe all mouse modes should be set to false - when either of these two modes are enabled */ - /* XXX can we cite something for this? -KJW 15Dec2014 */ - set_if_available( get_DEC_mode( 1000, fb ), false ); - set_if_available( get_DEC_mode( 1002, fb ), false ); - set_if_available( get_DEC_mode( 1005, fb ), false ); - set_if_available( get_DEC_mode( 1006, fb ), false ); + if (param == 9 || (param >= 1000 && param <= 1003)) { + fb->ds.mouse_reporting_mode = (Terminal::DrawState::MouseReportingMode) param; + } else if (param == 1005 || param == 1006 || param == 1015) { + fb->ds.mouse_encoding_mode = (Terminal::DrawState::MouseEncodingMode) param; + } else { + set_if_available( get_DEC_mode( param, fb ), true ); } - - set_if_available( get_DEC_mode( param, fb ), true ); } } @@ -312,7 +303,14 @@ void CSI_DECSM( Framebuffer *fb, Dispatcher *dispatch ) void CSI_DECRM( Framebuffer *fb, Dispatcher *dispatch ) { for ( int i = 0; i < dispatch->param_count(); i++ ) { - set_if_available( get_DEC_mode( dispatch->getparam( i, 0 ), fb ), false ); + int param = dispatch->getparam( i, 0 ); + if (param == 9 || (param >= 1000 && param <= 1003)) { + fb->ds.mouse_reporting_mode = Terminal::DrawState::MOUSE_REPORTING_NONE; + } else if (param == 1005 || param == 1006 || param == 1015) { + fb->ds.mouse_encoding_mode = Terminal::DrawState::MOUSE_ENCODING_DEFAULT; + } else { + set_if_available( get_DEC_mode( param, fb ), false ); + } } }