Browse Source

Added output_translate(): controls lf -> crlf translation

pull/857/head
Greg Ercolano 2 years ago
parent
commit
c568056244
  1. 20
      FL/Fl_Terminal.H
  2. 47
      src/Fl_Terminal.cxx
  3. 77
      test/terminal.fl

20
FL/Fl_Terminal.H

@ -329,6 +329,17 @@ public:
COLORMASK = (FG_XTERM | BG_XTERM) COLORMASK = (FG_XTERM | BG_XTERM)
}; };
/**
\enum OutFlags
Output translation flags for special control character translations.
*/
enum OutFlags {
OFF = 0x00, ///< no output translation
CR_TO_LF = 0x01, ///< carriage return generates a vertical line-feed (\\r -> \\n)
LF_TO_CR = 0x02, ///< line-feed generates a carriage return (\\n -> \\r)
LF_TO_CRLF = 0x04 ///< line-feed generates a carriage return line-feed (\\n -> \\r\\n)
};
/////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////
////// //////
////// Fl_Terminal Protected Classes ////// Fl_Terminal Protected Classes
@ -746,6 +757,7 @@ private:
Fl_Scrollbar *vscroll_; // vertical scrollbar (value: rows above disp_chars[]) Fl_Scrollbar *vscroll_; // vertical scrollbar (value: rows above disp_chars[])
int scrollbar_size_; // local preference for scrollbar size int scrollbar_size_; // local preference for scrollbar size
CharStyle *current_style_; // current font, attrib, color.. CharStyle *current_style_; // current font, attrib, color..
OutFlags oflags_; // output translation flags (CR_TO_LF, LF_TO_CR, LF_TO_CRLF)
// A ring buffer is used for the terminal's history (hist) and display (disp) buffer. // A ring buffer is used for the terminal's history (hist) and display (disp) buffer.
// See README-Fl_Terminal.txt, section "RING BUFFER DESCRIPTION" for diagrams/info. // See README-Fl_Terminal.txt, section "RING BUFFER DESCRIPTION" for diagrams/info.
@ -880,6 +892,13 @@ protected:
void cursor_tab_left(int count=1); void cursor_tab_left(int count=1);
void save_cursor(void); void save_cursor(void);
void restore_cursor(void); void restore_cursor(void);
// Output translation
public:
void output_translate(Fl_Terminal::OutFlags val);
Fl_Terminal::OutFlags output_translate(void) const;
protected:
void handle_lf(void);
void handle_cr(void);
// Printing // Printing
private: private:
void handle_ctrl(char c); void handle_ctrl(char c);
@ -897,7 +916,6 @@ private:
void repeat_char(char c, int rep); void repeat_char(char c, int rep);
void utf8_cache_clear(void); void utf8_cache_clear(void);
void utf8_cache_flush(void); void utf8_cache_flush(void);
// API: Character display output // API: Character display output
public: public:
void putchar(const char *text, int len, int drow, int dcol); void putchar(const char *text, int len, int drow, int dcol);

47
src/Fl_Terminal.cxx

@ -2339,13 +2339,51 @@ void Fl_Terminal::restore_cursor(void) {
////// PRINTING ////// ////// PRINTING //////
////////////////////// //////////////////////
// Handle '\r' output based on output translation flags
void Fl_Terminal::handle_cr(void) {
const bool do_scroll = true;
if (oflags_ & CR_TO_LF) cursor_down(1, do_scroll);
else cursor_cr();
}
// Handle '\n' output based on output translation flags
void Fl_Terminal::handle_lf(void) {
const bool do_scroll = true;
if (oflags_ & LF_TO_CR ) cursor_cr();
else if (oflags_ & LF_TO_CRLF) cursor_crlf();
else cursor_down(1, do_scroll);
}
/**
Sets the combined output translation flags to \p val.
\p val can be sensible combinations of the OutFlags bit flags.
The default is LF_TO_CRLF, so that \\n will generate both carriage-return (CR)
and line-feed (LF).
For \\r and \\n to be handled literally, use output_translate(Fl_Terminal::OutFlags::OFF);
To disable all output translations, use 0 or Fl_Terminal::OutFlags::OFF.
*/
void Fl_Terminal::output_translate(Fl_Terminal::OutFlags val) {
oflags_ = val;
}
/**
Return the current combined output translation flags.
*/
Fl_Terminal::OutFlags Fl_Terminal::output_translate(void) const {
return oflags_;
}
/** /**
Handle the special control character 'c'. Handle the special control character 'c'.
These are control characters that involve special terminal handling, e.g. These are control characters that involve special terminal handling, e.g.
\code \code
\r - carriage return - cursor_cr() \r - carriage return - default behavior for \r is CR. See output_translate()
\n - line feed - cursor_crlf() - default behavior for \n is CR and LF \n - line feed - default behavior for \n is CRLF. See output_translate()
\b - backspace - cursor_left() \b - backspace - cursor_left()
\t - tab - cursor_tab_right() \t - tab - cursor_tab_right()
\e - escape - starts an ANSI or xterm escape sequence \e - escape - starts an ANSI or xterm escape sequence
@ -2353,9 +2391,9 @@ void Fl_Terminal::restore_cursor(void) {
*/ */
void Fl_Terminal::handle_ctrl(char c) { void Fl_Terminal::handle_ctrl(char c) {
switch (c) { switch (c) {
case '\n': cursor_crlf(); return; // CRLF?
case '\b': cursor_left(); return; // BS? case '\b': cursor_left(); return; // BS?
case '\r': cursor_cr(); return; // CR? case '\r': handle_cr(); return; // CR?
case '\n': handle_lf(); return; // LF?
case '\t': cursor_tab_right(); return; // TAB? case '\t': cursor_tab_right(); return; // TAB?
case 0x1b: if (ansi_) escseq.parse(c); // ESC? case 0x1b: if (ansi_) escseq.parse(c); // ESC?
else append_utf8(""); else append_utf8("");
@ -3110,6 +3148,7 @@ Fl_Terminal::Fl_Terminal(int X,int Y,int W,int H,const char*L,int rows,int cols,
void Fl_Terminal::init_(int X,int Y,int W,int H,const char*L,int rows,int cols,int hist,bool fontsize_defer) { void Fl_Terminal::init_(int X,int Y,int W,int H,const char*L,int rows,int cols,int hist,bool fontsize_defer) {
fontsize_defer_ = fontsize_defer; // defer font calls until draw() (issue 837) fontsize_defer_ = fontsize_defer; // defer font calls until draw() (issue 837)
current_style_ = new CharStyle(fontsize_defer); current_style_ = new CharStyle(fontsize_defer);
oflags_ = LF_TO_CRLF; // default: "\n" handled as "\r\n"
// scrollbar_size must be set before scrn_ // scrollbar_size must be set before scrn_
scrollbar_size_ = 0; // 0 uses Fl::scrollbar_size() scrollbar_size_ = 0; // 0 uses Fl::scrollbar_size()
update_screen_xywh(); update_screen_xywh();

77
test/terminal.fl

@ -1408,7 +1408,7 @@ fl_alert("Illegal color value '%s'\\n(can be e.g. '12' or '\#0c', etc)", val_str
return -1;} {} return -1;} {}
} }
Function {update_inputs()} { Function {update_inputs()} {
comment {Resync the inputs with widget's values} return_type void comment {Resync the inputs with widget's values} open return_type void
} { } {
code {// Scroll History code {// Scroll History
scrollhistory_input->value( G_tty->history_rows() ); scrollhistory_input->value( G_tty->history_rows() );
@ -1496,14 +1496,32 @@ switch ( G_tty->box() ) {
char s[80]; char s[80];
sprintf(s, "\#%08x", G_tty->selectionfgcolor()); selectionfgcolor_input->value(s); sprintf(s, "\#%08x", G_tty->selectionfgcolor()); selectionfgcolor_input->value(s);
sprintf(s, "\#%08x", G_tty->selectionbgcolor()); selectionbgcolor_input->value(s); sprintf(s, "\#%08x", G_tty->selectionbgcolor()); selectionbgcolor_input->value(s);
}
// output_translate()
{
int out = G_tty->output_translate();
outflags_lf_to_crlf->value((out&Fl_Terminal::LF_TO_CRLF) ? 1 : 0);
outflags_lf_to_cr->value( (out&Fl_Terminal::LF_TO_CR) ? 1 : 0);
outflags_cr_to_lf->value( (out&Fl_Terminal::CR_TO_LF) ? 1 : 0);
}} {} }} {}
}
Function {handle_output_translate(void)} {
comment {Handle the output_translation() flags} open return_type void
} {
code {// Handle combining output_translate() flags..
int out = 0;
if ( outflags_lf_to_crlf->value() ) out |= Fl_Terminal::LF_TO_CRLF;
if ( outflags_lf_to_cr->value() ) out |= Fl_Terminal::LF_TO_CR;
if ( outflags_cr_to_lf->value() ) out |= Fl_Terminal::CR_TO_LF;
G_tty->output_translate(Fl_Terminal::OutFlags(out));} {}
} }
Function {make_window()} {open Function {make_window()} {open
} { } {
Fl_Window win { Fl_Window win {
label {Fl_Terminal Test} label {Fl_Terminal Test}
callback {exit(0);} open callback {exit(0);} open
xywh {0 0 897 838} type Double visible xywh {421 64 897 838} type Double visible
} { } {
Fl_Spinner scrollhistory_input { Fl_Spinner scrollhistory_input {
label {Scroll History} label {Scroll History}
@ -1621,6 +1639,10 @@ G_tty->redraw();}
xywh {10 10 100 20} labelsize 8 xywh {10 10 100 20} labelsize 8
} }
} }
Fl_Box {} {
label {Lt, Rt, Top, Bot}
xywh {110 172 114 15} labelsize 10
}
Fl_Input margins_input { Fl_Input margins_input {
label Margins label Margins
callback {int lt,rt,top,bot; callback {int lt,rt,top,bot;
@ -1636,31 +1658,42 @@ G_tty->margin_bottom(bot);
G_tty->redraw();} G_tty->redraw();}
xywh {110 187 114 20} labelsize 10 when 28 textsize 10 xywh {110 187 114 20} labelsize 10 when 28 textsize 10
} }
Fl_Check_Button outflags_lf_to_crlf {
label LF_TO_CRLF
callback {handle_output_translate();} selected
tooltip {Line-feed (\\n) performs carriage-return and line-feed (CRLF)} xywh {333 7 77 24} down_box DOWN_BOX labelsize 9
}
Fl_Check_Button outflags_lf_to_cr {
label LF_TO_CR
callback {handle_output_translate();} selected
tooltip {Line-feed (\\n) performs carriage-return (\\r)} xywh {432 7 70 24} down_box DOWN_BOX labelsize 9
}
Fl_Check_Button outflags_cr_to_lf {
label CR_TO_LF
callback {handle_output_translate();} selected
tooltip {Carriage-return (\\r) performs line-feed (\\n)} xywh {528 7 70 24} down_box DOWN_BOX labelsize 9
}
Fl_Check_Button showunknown_radio { Fl_Check_Button showunknown_radio {
label {show_unknown()} label {show_unknown()}
callback {G_tty->show_unknown(showunknown_radio->value() ? true : false); callback {G_tty->show_unknown(showunknown_radio->value() ? true : false);
G_tty->redraw();} G_tty->redraw();}
tooltip {Shows unknown escape sequences/unprintable chars as "¿" character} xywh {331 7 105 20} down_box DOWN_BOX labelsize 9 tooltip {Shows unknown escape sequences/unprintable chars as "¿" character} xywh {331 31 105 24} down_box DOWN_BOX labelsize 9
} }
Fl_Check_Button interactivecursor_radio { Fl_Check_Button interactivecursor_radio {
label {Interactive Cursor} label {Interactive Cursor}
callback {bool val = interactivecursor_radio->value() ? true : false; callback {bool val = interactivecursor_radio->value() ? true : false;
G_tty->interactive_cursor(val);} G_tty->interactive_cursor(val);}
tooltip {Allow Up/Dn/Lt/Rt keys to move cursor tooltip {Allow Up/Dn/Lt/Rt keys to move cursor
when terminal has focus} xywh {473 7 125 20} down_box DOWN_BOX labelsize 9 when terminal has focus} xywh {473 31 125 24} down_box DOWN_BOX labelsize 9
} }
Fl_Check_Button ansi_radio { Fl_Check_Button ansi_radio {
label {ansi()} label {ansi()}
callback {G_tty->ansi(ansi_radio->value() ? true : false);} callback {G_tty->ansi(ansi_radio->value() ? true : false);}
tooltip {Handle ANSI/xterm escape sequences} xywh {331 27 95 20} down_box DOWN_BOX labelsize 9 tooltip {Handle ANSI/xterm escape sequences} xywh {331 55 95 24} down_box DOWN_BOX labelsize 9
} }
Fl_Check_Button stdout_radio { Fl_Check_Button stdout_radio {
label {Echo tests to stdout} label {Echo tests to stdout}
tooltip {Also send test output to stdout} xywh {473 27 121 20} down_box DOWN_BOX labelsize 9 tooltip {Also send test output to stdout} xywh {473 55 125 24} down_box DOWN_BOX labelsize 9
}
Fl_Box {} {
label {Lt, Rt, Top, Bot}
xywh {110 172 114 15} labelsize 10
} }
Fl_Input textcolor_input { Fl_Input textcolor_input {
label {textcolor()} label {textcolor()}
@ -1673,7 +1706,7 @@ G_tty->redraw();}
tooltip {The widget's text color. Has the effect of simultaneously setting: tooltip {The widget's text color. Has the effect of simultaneously setting:
> textfgcolor() > textfgcolor()
>textfgcolor_default() >textfgcolor_default()
Can be decimal (e.g. 12) or hex (e.g. \#0c, \#0000000c, etc)} xywh {333 55 77 20} labelsize 9 when 28 textfont 4 textsize 9 Can be decimal (e.g. 12) or hex (e.g. \#0c, \#0000000c, etc)} xywh {333 79 77 20} labelsize 9 when 28 textfont 4 textsize 9
} }
Fl_Input textfgcolor_input { Fl_Input textfgcolor_input {
label {textfgcolor()} label {textfgcolor()}
@ -1684,7 +1717,7 @@ update_inputs();
//DEBUG ::printf("IVAL is %08lx\\n",ival); //DEBUG ::printf("IVAL is %08lx\\n",ival);
G_tty->redraw();} G_tty->redraw();}
tooltip {The text foreground color. tooltip {The text foreground color.
Can be decimal (e.g. 12) or hex (e.g. \#0c, \#0000000c, etc)} xywh {333 79 77 20} labelsize 9 when 28 textfont 4 textsize 9 Can be decimal (e.g. 12) or hex (e.g. \#0c, \#0000000c, etc)} xywh {333 103 77 20} labelsize 9 when 28 textfont 4 textsize 9
} }
Fl_Input textfgcolor_default_input { Fl_Input textfgcolor_default_input {
label {textfgcolor_default()} label {textfgcolor_default()}
@ -1695,7 +1728,7 @@ update_inputs();
//DEBUG ::printf("IVAL is %08lx\\n",ival); //DEBUG ::printf("IVAL is %08lx\\n",ival);
G_tty->redraw();} G_tty->redraw();}
tooltip {The text foreground default color. tooltip {The text foreground default color.
Can be decimal (e.g. 12) or hex (e.g. \#0c, \#0000000c, etc)} xywh {333 103 77 20} labelsize 9 when 28 textfont 4 textsize 9 Can be decimal (e.g. 12) or hex (e.g. \#0c, \#0000000c, etc)} xywh {333 127 77 20} labelsize 9 when 28 textfont 4 textsize 9
} }
Fl_Input cursorfgcolor_input { Fl_Input cursorfgcolor_input {
label {cursorfgcolor()} label {cursorfgcolor()}
@ -1705,7 +1738,7 @@ G_tty->cursorfgcolor(c);
update_inputs(); update_inputs();
//DEBUG ::printf("IVAL is %08lx\\n",ival); //DEBUG ::printf("IVAL is %08lx\\n",ival);
G_tty->redraw();} G_tty->redraw();}
tooltip {Foreground color for text under the cursor.} xywh {333 127 77 20} labelsize 9 when 28 textfont 4 textsize 9 tooltip {Foreground color for text under the cursor.} xywh {333 151 77 20} labelsize 9 when 28 textfont 4 textsize 9
} }
Fl_Input selectionfgcolor_input { Fl_Input selectionfgcolor_input {
label {selectionfgcolor()} label {selectionfgcolor()}
@ -1716,7 +1749,7 @@ update_inputs();
//DEBUG ::printf("IVAL is %08lx\\n",ival); //DEBUG ::printf("IVAL is %08lx\\n",ival);
G_tty->redraw();} G_tty->redraw();}
tooltip {The mouse selection foreground color. tooltip {The mouse selection foreground color.
Can be decimal (e.g. 12) or hex (e.g. \#0c, \#0000000c, etc)} xywh {333 151 77 20} labelsize 9 when 28 textfont 4 textsize 9 Can be decimal (e.g. 12) or hex (e.g. \#0c, \#0000000c, etc)} xywh {333 175 77 20} labelsize 9 when 28 textfont 4 textsize 9
} }
Fl_Input color_input { Fl_Input color_input {
label {color()} label {color()}
@ -1727,7 +1760,7 @@ update_inputs();
//DEBUG ::printf("IVAL is %08lx\\n",ival); //DEBUG ::printf("IVAL is %08lx\\n",ival);
G_tty->redraw();} G_tty->redraw();}
tooltip {The widget's background color(). tooltip {The widget's background color().
Can be decimal (e.g. 12) or hex (e.g. \#0c, \#0000000c, etc)} xywh {521 55 77 20} labelsize 9 when 28 textfont 4 textsize 9 Can be decimal (e.g. 12) or hex (e.g. \#0c, \#0000000c, etc)} xywh {521 79 77 20} labelsize 9 when 28 textfont 4 textsize 9
} }
Fl_Input textbgcolor_input { Fl_Input textbgcolor_input {
label {textbgcolor()} label {textbgcolor()}
@ -1739,7 +1772,7 @@ update_inputs();
G_tty->redraw();} G_tty->redraw();}
tooltip {The text background color. tooltip {The text background color.
Refer to the docs for the special value 0xffffffff. Refer to the docs for the special value 0xffffffff.
Can be decimal (e.g. 12) or hex (e.g. \#0c, \#0000000c, etc)} xywh {521 79 77 20} labelsize 9 when 28 textfont 4 textsize 9 Can be decimal (e.g. 12) or hex (e.g. \#0c, \#0000000c, etc)} xywh {521 103 77 20} labelsize 9 when 28 textfont 4 textsize 9
} }
Fl_Input textbgcolor_default_input { Fl_Input textbgcolor_default_input {
label {textbgcolor_default()} label {textbgcolor_default()}
@ -1751,7 +1784,7 @@ update_inputs();
G_tty->redraw();} G_tty->redraw();}
tooltip {The text background default color. tooltip {The text background default color.
Refer to the docs for the special value 0xffffffff. Refer to the docs for the special value 0xffffffff.
Can be decimal (e.g. 12) or hex (e.g. \#0c, \#0000000c, etc)} xywh {521 103 77 20} labelsize 9 when 28 textfont 4 textsize 9 Can be decimal (e.g. 12) or hex (e.g. \#0c, \#0000000c, etc)} xywh {521 127 77 20} labelsize 9 when 28 textfont 4 textsize 9
} }
Fl_Input cursorbgcolor_input { Fl_Input cursorbgcolor_input {
label {cursorbgcolor()} label {cursorbgcolor()}
@ -1762,7 +1795,7 @@ update_inputs();
//DEBUG ::printf("IVAL is %08lx\\n",ival); //DEBUG ::printf("IVAL is %08lx\\n",ival);
G_tty->redraw();} G_tty->redraw();}
tooltip {Background color for the cursor. tooltip {Background color for the cursor.
This is the cursor block's color} xywh {521 127 77 20} labelsize 9 when 28 textfont 4 textsize 9 This is the cursor block's color} xywh {521 151 77 20} labelsize 9 when 28 textfont 4 textsize 9
} }
Fl_Input selectionbgcolor_input { Fl_Input selectionbgcolor_input {
label {selectionbgcolor()} label {selectionbgcolor()}
@ -1773,11 +1806,11 @@ update_inputs();
//DEBUG ::printf("IVAL is %08lx\\n",ival); //DEBUG ::printf("IVAL is %08lx\\n",ival);
G_tty->redraw();} G_tty->redraw();}
tooltip {The mouse selection background color. tooltip {The mouse selection background color.
Can be decimal (e.g. 12) or hex (e.g. \#0c, \#0000000c, etc)} xywh {521 151 77 20} labelsize 9 when 28 textfont 4 textsize 9 Can be decimal (e.g. 12) or hex (e.g. \#0c, \#0000000c, etc)} xywh {521 175 77 20} labelsize 9 when 28 textfont 4 textsize 9
} }
Fl_Choice {} { Fl_Choice {} {
label {Terminal Color} label {Terminal Color}
xywh {389 187 145 20} down_box BORDER_BOX labelsize 9 textsize 9 xywh {389 211 145 20} down_box BORDER_BOX labelsize 9 textsize 9
} { } {
MenuItem {} { MenuItem {} {
label {White on DarkAmber} label {White on DarkAmber}
@ -1933,7 +1966,7 @@ if (scrollhistory_input->value() > 35) {
} }
// Show debug window // Show debug window
G_tty->show_ring_debug_window();} selected G_tty->show_ring_debug_window();}
tooltip {Show the Fl_Terminal raw ring buffer contents. tooltip {Show the Fl_Terminal raw ring buffer contents.
(Warning: This slows the UI and uses continuous cpu until closed)} xywh {640 198 90 25} labelsize 11 (Warning: This slows the UI and uses continuous cpu until closed)} xywh {640 198 90 25} labelsize 11
} }

Loading…
Cancel
Save