Added output_translate(): controls lf -> crlf translation

This commit is contained in:
Greg Ercolano 2023-11-21 11:23:58 -08:00
parent 56e85e8522
commit c568056244
3 changed files with 117 additions and 27 deletions

View File

@ -329,6 +329,17 @@ public:
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
@ -746,6 +757,7 @@ private:
Fl_Scrollbar *vscroll_; // vertical scrollbar (value: rows above disp_chars[])
int scrollbar_size_; // local preference for scrollbar size
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.
// 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 save_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
private:
void handle_ctrl(char c);
@ -897,7 +916,6 @@ private:
void repeat_char(char c, int rep);
void utf8_cache_clear(void);
void utf8_cache_flush(void);
// API: Character display output
public:
void putchar(const char *text, int len, int drow, int dcol);

View File

@ -2339,13 +2339,51 @@ void Fl_Terminal::restore_cursor(void) {
////// 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'.
These are control characters that involve special terminal handling, e.g.
\code
\r - carriage return - cursor_cr()
\n - line feed - cursor_crlf() - default behavior for \n is CR and LF
\r - carriage return - default behavior for \r is CR. See output_translate()
\n - line feed - default behavior for \n is CRLF. See output_translate()
\b - backspace - cursor_left()
\t - tab - cursor_tab_right()
\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) {
switch (c) {
case '\n': cursor_crlf(); return; // CRLF?
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 0x1b: if (ansi_) escseq.parse(c); // ESC?
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) {
fontsize_defer_ = fontsize_defer; // defer font calls until draw() (issue 837)
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_ = 0; // 0 uses Fl::scrollbar_size()
update_screen_xywh();

View File

@ -1408,7 +1408,7 @@ fl_alert("Illegal color value '%s'\\n(can be e.g. '12' or '\#0c', etc)", val_str
return -1;} {}
}
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
scrollhistory_input->value( G_tty->history_rows() );
@ -1496,14 +1496,32 @@ switch ( G_tty->box() ) {
char s[80];
sprintf(s, "\#%08x", G_tty->selectionfgcolor()); selectionfgcolor_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
} {
Fl_Window win {
label {Fl_Terminal Test}
callback {exit(0);} open
xywh {0 0 897 838} type Double visible
xywh {421 64 897 838} type Double visible
} {
Fl_Spinner scrollhistory_input {
label {Scroll History}
@ -1621,6 +1639,10 @@ G_tty->redraw();}
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 {
label Margins
callback {int lt,rt,top,bot;
@ -1636,31 +1658,42 @@ G_tty->margin_bottom(bot);
G_tty->redraw();}
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 {
label {show_unknown()}
callback {G_tty->show_unknown(showunknown_radio->value() ? true : false);
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 {
label {Interactive Cursor}
callback {bool val = interactivecursor_radio->value() ? true : false;
G_tty->interactive_cursor(val);}
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 {
label {ansi()}
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 {
label {Echo tests to stdout}
tooltip {Also send test output to stdout} xywh {473 27 121 20} down_box DOWN_BOX labelsize 9
}
Fl_Box {} {
label {Lt, Rt, Top, Bot}
xywh {110 172 114 15} labelsize 10
tooltip {Also send test output to stdout} xywh {473 55 125 24} down_box DOWN_BOX labelsize 9
}
Fl_Input textcolor_input {
label {textcolor()}
@ -1673,7 +1706,7 @@ G_tty->redraw();}
tooltip {The widget's text color. Has the effect of simultaneously setting:
> textfgcolor()
>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 {
label {textfgcolor()}
@ -1684,7 +1717,7 @@ update_inputs();
//DEBUG ::printf("IVAL is %08lx\\n",ival);
G_tty->redraw();}
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 {
label {textfgcolor_default()}
@ -1695,7 +1728,7 @@ update_inputs();
//DEBUG ::printf("IVAL is %08lx\\n",ival);
G_tty->redraw();}
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 {
label {cursorfgcolor()}
@ -1705,7 +1738,7 @@ G_tty->cursorfgcolor(c);
update_inputs();
//DEBUG ::printf("IVAL is %08lx\\n",ival);
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 {
label {selectionfgcolor()}
@ -1716,7 +1749,7 @@ update_inputs();
//DEBUG ::printf("IVAL is %08lx\\n",ival);
G_tty->redraw();}
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 {
label {color()}
@ -1727,7 +1760,7 @@ update_inputs();
//DEBUG ::printf("IVAL is %08lx\\n",ival);
G_tty->redraw();}
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 {
label {textbgcolor()}
@ -1739,7 +1772,7 @@ update_inputs();
G_tty->redraw();}
tooltip {The text background color.
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 {
label {textbgcolor_default()}
@ -1751,7 +1784,7 @@ update_inputs();
G_tty->redraw();}
tooltip {The text background default color.
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 {
label {cursorbgcolor()}
@ -1762,7 +1795,7 @@ update_inputs();
//DEBUG ::printf("IVAL is %08lx\\n",ival);
G_tty->redraw();}
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 {
label {selectionbgcolor()}
@ -1773,11 +1806,11 @@ update_inputs();
//DEBUG ::printf("IVAL is %08lx\\n",ival);
G_tty->redraw();}
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 {} {
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 {} {
label {White on DarkAmber}
@ -1933,7 +1966,7 @@ if (scrollhistory_input->value() > 35) {
}
// 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.
(Warning: This slows the UI and uses continuous cpu until closed)} xywh {640 198 90 25} labelsize 11
}