diff --git a/FL/Fl_Simple_Terminal.H b/FL/Fl_Simple_Terminal.H index 10ed81bdb..74b012810 100644 --- a/FL/Fl_Simple_Terminal.H +++ b/FL/Fl_Simple_Terminal.H @@ -161,7 +161,6 @@ private: private: int history_lines_; // max lines allowed in screen history bool stay_at_bottom_; // lets scroller chase last line in buffer - bool ansi_; // enables ANSI sequences // scroll management int lines_; // #lines in buffer (optimization: Fl_Text_Buffer slow to calc this) bool scrollaway_; // true when user changed vscroll away from bottom @@ -175,7 +174,10 @@ private: int normal_style_index_; // "normal" style used by "\033[0m" reset sequence int current_style_index_; // current style used for drawing text char current_style_; // current 'style char' (e.g. 'A' = first style entry) + // ANSI escape seq Fl_Escape_Seq escseq; // escape sequence state handler + bool ansi_; // enables ANSI sequences + bool ansi_show_unknown_; // show '¿' for unknown ESC sequences (default: off) // String parsing vars initialized/used by append(), used by handle_backspace() etc. char *ntm_; // new text memory (ntm) - malloc()ed by append() for output text char *ntp_; // new text ptr (ntp) - points into ntm buffer @@ -193,6 +195,8 @@ public: int history_lines() const; void ansi(bool val); bool ansi() const; + void ansi_show_unknown(bool val); + bool ansi_show_unknown() const; void style_table(Fl_Text_Display::Style_Table_Entry *stable, int stable_size, int normal_style_index=0); const Fl_Text_Display::Style_Table_Entry *style_table() const; int style_table_size() const; @@ -234,6 +238,7 @@ protected: void backspace_buffer(unsigned int count); void handle_backspace(); void append_ansi(const char *s, int len); + void unknown_escape(); }; #endif diff --git a/src/Fl_Simple_Terminal.cxx b/src/Fl_Simple_Terminal.cxx index 680b157dd..3f7ade3eb 100644 --- a/src/Fl_Simple_Terminal.cxx +++ b/src/Fl_Simple_Terminal.cxx @@ -287,7 +287,6 @@ void Fl_Simple_Terminal::vscroll_cb(Fl_Widget *w, void *data) { Fl_Simple_Terminal::Fl_Simple_Terminal(int X,int Y,int W,int H,const char *l) : Fl_Text_Display(X,Y,W,H,l) { history_lines_ = 500; // something 'reasonable' stay_at_bottom_ = true; - ansi_ = false; lines_ = 0; // note: lines!=mNBufferLines when lines are wrapping scrollaway_ = false; scrolling_ = false; @@ -312,6 +311,9 @@ Fl_Simple_Terminal::Fl_Simple_Terminal(int X,int Y,int W,int H,const char *l) : normal_style_index_ = builtin_normal_index; current_style_index_ = builtin_normal_index; current_style_ = 'A' + 0; + // ANSI escape seq + ansi_ = false; + ansi_show_unknown_ = false; // Intercept vertical scrolling orig_vscroll_cb_ = mVScrollBar->callback(); orig_vscroll_data_ = mVScrollBar->user_data(); @@ -470,6 +472,23 @@ void Fl_Simple_Terminal::ansi(bool val) { redraw(); } +/** + See if we should show unknown ANSI sequences with '¿' or not. + \see ansi_show_unknown(bool) +*/ +bool Fl_Simple_Terminal::ansi_show_unknown(void) const { + return ansi_show_unknown_; +} + +/** + Enable showing unknown ESC sequences with the '¿' character. + By default this is off, and unknown escape sequences are silently ignored. + \see ansi_show_unknown() +*/ +void Fl_Simple_Terminal::ansi_show_unknown(bool val) { + ansi_show_unknown_ = val; +} + /** Return the current style table being used. @@ -760,6 +779,16 @@ void Fl_Simple_Terminal::handle_backspace() { backspace_buffer(1); } +// Handle unknown esc sequences +void Fl_Simple_Terminal::unknown_escape() { + if ( ansi_show_unknown() ) { + for ( const char *s = "¿"; *s; s++ ) { + *ntp_++ = *s; // emit utf-8 encoded char + *nsp_++ = current_style(); // use current style + } + } +} + /** Handle appending string with ANSI escape sequences, and other 'special' character processing (such as backspaces). @@ -782,6 +811,7 @@ void Fl_Simple_Terminal::append_ansi(const char *s, int len) { if ( escseq.parse_in_progress() ) { // ESC sequence in progress? switch ( escseq.parse(*sp) ) { // parse until completed or fail case Fl_Escape_Seq::fail: // parsing error? + unknown_escape(); escseq.reset(); // ..reset and continue ++sp; continue; @@ -801,10 +831,10 @@ void Fl_Simple_Terminal::append_ansi(const char *s, int len) { case 'J': // ESC[#J switch (val) { case 0: // ESC[0J -- clear to eol - // unsupported + unknown_escape(); break; case 1: // ESC[1J -- clear to sol - // unsupported + unknown_escape(); break; case 2: // ESC[2J -- clear visible screen // NOTE: Currently we clear the /entire screen history/, and @@ -817,6 +847,9 @@ void Fl_Simple_Terminal::append_ansi(const char *s, int len) { ntp_ = ntm_; // clear text contents accumulated so far nsp_ = nsm_; // clear style contents "" break; + default: // all other ESC[#J unsupported + unknown_escape(); + break; } break; // SELECT GRAPHIC RENDITION (SGR) @@ -831,6 +864,7 @@ void Fl_Simple_Terminal::append_ansi(const char *s, int len) { break; // UNSUPPORTED MODES default: + unknown_escape(); break; // unsupported } }