Fl_Terminal: address docs related fixes (#1578)

Codex assisted code review limited to documentation related
issues with the Fl_Terminal widget.

Most fixes grammatical, typos, and and other common human error
stuff. A few code changes where the docs were correct but the
implementation was wrong.

Generally, I think these mods would be safe to backport to 1.4.x
(if that's within the scope of 1.4.x), as these aren't features
or behavioral changes, but outright misleading documentation,
or implementations incorrect wrt the docs.
This commit is contained in:
Greg Ercolano
2026-08-13 12:21:19 -07:00
parent 7e62b5ce97
commit fc078b1b4d
3 changed files with 80 additions and 82 deletions
+28 -28
View File
@@ -36,7 +36,7 @@
\brief Terminal widget supporting Unicode/utf-8, ANSI/xterm escape codes with full RGB color control.
\section Fl_Terminal
\section Fl_Terminal The Fl_Terminal Widget
\image html Fl_Terminal-demo.png "Fl_Terminal widget showing a linux manual page"
\image latex Fl_Terminal-demo.png "Fl_Terminal widget showing a linux manual page" width=6cm
@@ -54,10 +54,10 @@
clear_screen_home() | ESC [ H ESC [ 2 J | Clear screen, home cursor |
cursor_home() | ESC [ H | Home the cursor |
clear_history() | ESC [ 3 J | Clear scrollback history |
reset_terminal() | ESC [ c | Reset terminal |
reset_terminal() | ESC c | Reset terminal |
To access more advanced API calls, one can derive a class from Fl_Terminal to
access protected methods manipulate the terminal more directly, e.g.
access protected methods and manipulate the terminal more directly, e.g.
\par
Protected API | ESC code equiv. | Description |
-----------------------------|------------------|-----------------------------------------|
@@ -71,8 +71,8 @@
scroll(int) // <0 for down | ESC [ 1 T | Scroll down one line |
cursor_left() | ESC [ 1 D | Move cursor left (no wrap) |
cursor_right() | ESC [ 1 C | Move cursor right (no wrap) |
cursor_up() | ESC [ 1 B | Move cursor up (no scroll or wrap) |
cursor_down() | ESC [ 1 A | Move cursor down (no scroll or wrap) |
cursor_up() | ESC [ 1 A | Move cursor up (no scroll or wrap) |
cursor_down() | ESC [ 1 B | Move cursor down (no scroll or wrap) |
cursor_row() cursor_col() | ESC [ # ; # H | Move cursor to row# / column# |
insert_char() | ESC [ # @ | Insert a char at cursor position |
delete_chars() | ESC [ # P | Delete chars at cursor position |
@@ -117,7 +117,7 @@
or clear the screen via application control, e.g.
\par
\code
tty->home(); // home the cursor
tty->cursor_home(); // home the cursor
tty->clear_screen(); // clear the screen
tty->textfgcolor(0xff000000); // change the text color to RED
tty->textbgcolor(0x0000ff00); // change the background color to BLUE
@@ -169,14 +169,14 @@
\par
There's at least two ways to specify colors for text and background colors:
\par
- 3 bit / 8 Color Values
- Full 24 bit R/G/B colors
- 3-bit / 8-color values
- Full 24-bit R/G/B colors
\par
Example of 3 bit colors:
\image html Fl_Terminal-3bit-colors.png "Fl_Terminal 3 bit colors"
\image latex Fl_Terminal-3bit-colors.png "Fl_Terminal 3 bit colors" width=6cm
Example of 3-bit colors:
\image html Fl_Terminal-3bit-colors.png "Fl_Terminal 3-bit colors"
\image latex Fl_Terminal-3bit-colors.png "Fl_Terminal 3-bit colors" width=6cm
\par
Example application source code using 3 bit colors:
Example application source code using 3-bit colors:
\code
//
// Text colors
@@ -196,20 +196,20 @@
tty->append("\033[47m White Background.\033[0m\n");
\endcode
\par
Example of 24 bit colors:
\image html Fl_Terminal-24bit-colors.png "Fl_Terminal 24 bit colors"
\image latex Fl_Terminal-24bit-colors.png "Fl_Terminal 24 bit colors" width=6cm
Example of 24-bit colors:
\image html Fl_Terminal-24bit-colors.png "Fl_Terminal 24-bit colors"
\image latex Fl_Terminal-24bit-colors.png "Fl_Terminal 24-bit colors" width=6cm
\par
Example application source code using 24 bit colors:
Example application source code using 24-bit colors:
\code
//
// 24 bit Text Color
// 24-bit Text Color
//
tty->append("\033[38;2;0;0;255m Text is BLUE.\033[0m\n"); // RGB: R=0, G=0, B=255
tty->append("\033[38;2;255;0;0m Text is RED.\033[0m\n"); // RGB: R=255, G=0, B=0
tty->append("\033[38;2;127;64;0m Text is DARK ORANGE.\033[0m\n"); // RGB: R=127, G=64, B=0
//
// 24 bit Background Color
// 24-bit Background Color
//
tty->append("\033[48;2;0;0;255m Background is BLUE.\033[0m\n"); // RGB: R=0, G=0, B=255
tty->append("\033[48;2;255;0;0m Background is RED.\033[0m\n"); // RGB: R=255, G=0, B=0
@@ -488,7 +488,7 @@ protected:
void sgr_bold(bool val) { attrib_ = (uchar)onoff(val, Fl_Terminal::BOLD); } // e.g. ESC[1m
void sgr_dim(bool val) { attrib_ = (uchar)onoff(val, Fl_Terminal::DIM); } // e.g. ESC[2m
void sgr_italic(bool val) { attrib_ = (uchar)onoff(val, Fl_Terminal::ITALIC); } // e.g. ESC[3m
void sgr_underline(bool val) { attrib_ = (uchar)onoff(val, Fl_Terminal::UNDERLINE); } // e.g. ESC[3m
void sgr_underline(bool val) { attrib_ = (uchar)onoff(val, Fl_Terminal::UNDERLINE); } // e.g. ESC[4m
void sgr_dbl_under(bool val) { attrib_ = (uchar)onoff(val, Fl_Terminal::UNDERLINE); } // e.g. ESC[21m (TODO!)
void sgr_blink(bool val) { (void)val; /* NOT IMPLEMENTED */ } // e.g. ESC[5m
void sgr_inverse(bool val) { attrib_ = (uchar)onoff(val, Fl_Terminal::INVERSE); } // e.g. ESC[7m
@@ -544,8 +544,8 @@ protected:
uchar len_; // length of bytes in text_[] buffer; 1 for ASCII, >1 for UTF-8
uchar attrib_; // attribute bits for this char (bold, underline..)
uchar charflags_; // CharFlags (xterm colors management)
Fl_Color fgcolor_; // fltk fg color (supports 8color or 24bit color set w/ESC[37;<r>;<g>;<b>m)
Fl_Color bgcolor_; // fltk bg color (supports 8color or 24bit color set w/ESC[47;<r>;<g>;<b>m)
Fl_Color fgcolor_; // fltk fg color (supports 8color or 24bit color set w/ESC[38;2;<r>;<g>;<b>m)
Fl_Color bgcolor_; // fltk bg color (supports 8color or 24bit color set w/ESC[48;2;<r>;<g>;<b>m)
// Private methods
void text_utf8_(const char *text, int len);
Fl_Color attr_color_(Fl_Color col, const Fl_Widget *grp) const;
@@ -615,10 +615,10 @@ private:
//
// The 'offset' concept allows the 'history' and 'display'
// to be scrolled indefinitely. The 'offset' is applied
// to all the row accesses, and are clamped to within their bounds.
// to all row accesses, and is wrapped within the buffer.
//
// For 'raw' access to the ring (without the offset concept),
// use the ring_chars() method, and walk from 0 - ring_rows().
// use the ring_chars() method, and walk from 0 - ring_rows()-1.
//
// _____________
// | | <- hist_srow() <- ring_srow()
@@ -715,7 +715,7 @@ private:
Fl_Color selectionfgcolor(void) const { return selectionfgcolor_; }
Fl_Color selectionbgcolor(void) const { return selectionbgcolor_; }
bool is_selection(void) const { return is_selection_; }
bool get_selection(int &srow,int &scol,int &erow,int &ecol) const; // guarantees return (start < end)
bool get_selection(int &srow,int &scol,int &erow,int &ecol) const;
bool start(int row, int col, bool char_right);
bool extend(int row, int col, bool char_right);
void end(void);
@@ -824,12 +824,12 @@ public:
- \ref Fl_Scrollbar::value(int) "scrollbar->value(int)" similarly sets the row
offset, which should be in the range [0 .. Fl_Scrollbar::maximum()].
- \ref Fl_Scrollbar::step(double) "scrollbar->step(double)" sets the smoothness
of scrolling, default is 0.25 for 4 steps of motion per column.
of scrolling, default is 0.25 for 4 steps of motion per row.
\todo Support scrollbar_left/right() - See Fl_Browser_::scrollbar docs
\todo Support new ScrollbarStyle
*/
Fl_Scrollbar *scrollbar; // vertical scrollbar (value: rows above disp_chars[])
Fl_Scrollbar *scrollbar; // vertical scrollbar (value: rows above the display)
/**
Horizontal scrollbar. This is public so it can be accessed directly, e.g.
@@ -867,8 +867,8 @@ private:
int autoscroll_dir_; // 0=autoscroll timer off, 3=scrolling up, 4=scrolling down
int autoscroll_amt_; // #pixels above or below edge, used for autoscroll speed
RedrawStyle redraw_style_; // NO_REDRAW, RATE_LIMITED, PER_WRITE
float redraw_rate_; // maximum redraw rate in seconds, default=0.10
bool redraw_modified_; // display modified; used by update_cb() to rate limit redraws
float redraw_rate_; // maximum redraw rate in seconds, default=0.10 (10 per sec)
bool redraw_modified_; // display modified; used by redraw_timer_cb() to rate limit redraws
bool redraw_timer_; // if true, redraw timer is running
PartialUtf8Buf pub_; // handles Partial Utf8 Buffer (pub)
+15 -15
View File
@@ -135,7 +135,7 @@ Features will be added as the widget matures.
│ └── ESC [ 48 ; 2; Red ; Grn ; Blue m - Background 8-bit Red,Grn,Blu values (in decimal 0-255)
│ ESC[s - save cursor pos (ansi.sys+xterm+gnome, but NOT vt100)
│ ESC[u - rest cursor pos (ansi.sys+xterm+gnome, but NOT vt100)
│ ESC[u - restore cursor pos (ansi.sys+xterm+gnome, but NOT vt100)
│ ESC[>#q - (DECSCA) Set Cursor style (block/line/blink..) (NOT IMPLEMENTED)
│ ESC[#;#r - (DECSTBM) Set scroll Region top;bot (NOT IMPLEMENTED)
@@ -151,7 +151,7 @@ Features will be added as the widget matures.
│ <ESC>H - (HTS) Horizontal Tab Set: set a tabstop
│ <ESC>M - (RI) Reverse Index (up w/scroll)
│ NOTE: Acronyms in parens are Digital Equipment Corporation's names these VT features.
│ NOTE: Acronyms in parens are Digital Equipment Corporation's names for these VT features.
\endcode
@@ -178,7 +178,7 @@ implement Fl_Terminal:
- Escape code management to implement VT100 style / ANSI escape codes.
A class was created for each character, since characters can be either ASCII
or Utf8 encoded byte sequences. This class is called Utf8Char, and handles
or UTF-8 encoded byte sequences. This class is called Utf8Char, and handles
the character, its fg and bg color, and any attributes like dim, bold, italic, etc.
For managing the screen, after various experiments, I decided a ring buffer
@@ -238,7 +238,7 @@ array of Utf8Chars called "ring_chars" whose width is ring_cols()
and whose height is ring_rows().
The "top" part of the ring is the history, whose width is hist_cols()
and whose height is hist_rows(). hist_use_rows() is used to define
and whose height is hist_rows(). hist_use() is used to define
what part of the history is currently in use.
The "bottom" part of the ring is the display, whose width is disp_cols()
@@ -287,9 +287,9 @@ Methods are used to allow direct access to the characters
in the buffer that automatically handle the offset and modulus
formulas, namely:
u8c_ring_row(row,col) // access the entire ring by row/col
u8c_hist_row(row,col) // access just the history buffer
u8c_disp_row(row,col) // access just the display buffer
u8c_ring_row(row)+col // access the entire ring by row/col
u8c_hist_row(row)+col // access just the history buffer
u8c_disp_row(row)+col // access just the display buffer
A key concept is the use of the simple 'offset' index integer
to allow the starting point of the history and display to be
@@ -363,8 +363,8 @@ into the ring:
act_ring_index = (histrows // the display exists AFTER the history, so offset the hist_rows
+ offset // include the scroll 'offset'
+ disp_row // add the desired row relative to the top of the display (0..disp_rows)
) % ring_rows; // make sure the resulting index is within the ring buffer (0..ring_rows)
+ disp_row // add the desired row relative to the top of the display (0..disp_rows-1)
) % ring_rows; // make sure the resulting index is within the ring buffer (0..ring_rows-1)
An additional bit of math makes sure if a negative result occurs, that
negative value works relative to the end of the ring, e.g.
@@ -397,7 +397,7 @@ in the row is just a simple integer offset:
So to recap, the concepts here are:
- The ring buffer itself, a linear array that is conceptually
split into a 2 dimensional array of rows and columns whose
split into a two-dimensional array of rows and columns whose
height and width are:
ring_rows -- how many rows in the entire ring buffer
@@ -435,8 +435,8 @@ So to recap, the concepts here are:
disp_erow() -- end row index of the display
The values returned by these are as described above.
For the hist_xxx() and disp_xxx() methods the 'offset' included into
the forumula. (For this reason hist_srow() won't always be zero
For the hist_xxx() and disp_xxx() methods, the 'offset' is included into
the formula. (For this reason hist_srow() won't always be zero
the way ring_srow() is, due to the 'offset')
The values returned by these methods can all be passed to the
@@ -491,14 +491,14 @@ slowly, the user won't see new information appear in a timely manner.
To solve this, a rate timer is used to prevent too many redraws:
- When new data comes in, a 1/10 sec timer is started and a modify flag is set.
- When new data arrives, a short .01-sec initial timer is started, and a modified flag is set.
- redraw() is NOT called yet, allowing more data to continue to arrive quickly
- When the 1/10th second timer fires, the callback checks the modify flag:
- if set, calls redraw(), resets the modify to 0, and calls
Fl::repeat_timeout() to repeat the callback in another 1/10th sec.
- if set, calls redraw(), resets the modify to 0, and calls Fl::repeat_timeout()
to repeat the callback after the configured redraw_rate() interval.
- if clear, no new data came in, so DISABLE the timer, done.
+37 -39
View File
@@ -154,7 +154,7 @@ Fl_Terminal::Selection::Selection(Fl_Terminal *terminal)
/**
Return selection start/end.
Ensures (start < end) to allow walking 'forward' thru selection,
Ensures (start <= end) to allow walking 'forward' thru selection,
left-to-right, top-to-bottom.
Returns:
@@ -166,7 +166,7 @@ bool Fl_Terminal::Selection::get_selection(int &srow,int &scol,
srow = srow_; scol = scol_;
erow = erow_; ecol = ecol_;
if (!is_selection_) return false;
// Ensure (start < end) on return
// Ensure (start <= end) on return
if (srow_ == erow_ && scol_ > ecol_) swap(scol, ecol);
if (srow_ > erow_)
{ swap(srow, erow); swap(scol, ecol); }
@@ -223,7 +223,7 @@ bool Fl_Terminal::Selection::extend(int row, int col, bool char_right) {
bool changed = ( (osrow != srow_) || (oerow != erow_)
|| (oscol != scol_) || (oecol != ecol_)
|| (oselection != is_selection_) );
return !changed;
return changed;
}
// End selection (turn dragging() off)
@@ -347,7 +347,7 @@ bool Fl_Terminal::EscapeSeq::parse_in_progress(void) const {
return (esc_mode_ == 0) ? false : true;
}
// See if we're in the middle of parsing an ESC sequence
// See if the escape sequence is a CSI sequence
bool Fl_Terminal::EscapeSeq::is_csi(void) const { return csi_; }
// Return with default value (if none) or vals[0] (if at least one val spec'd).
@@ -386,7 +386,7 @@ void Fl_Terminal::EscapeSeq::restore_cursor(int &row, int &col) {
int Fl_Terminal::EscapeSeq::parse(char c) {
// NOTE: During parsing esc_mode() will be:
// 0 - reset/not parsing
// 0x1b - ESC received, expecting next one of A/B/C/D or '['
// 0x1b - ESC received, expecting '[' or a supported final character
// '[' - actively parsing CSI sequence, e.g. ESC[
//
// At the /end/ of parsing, after 'completed' is returned,
@@ -608,7 +608,7 @@ void Fl_Terminal::Utf8Char::text_utf8(const char *text,
//
void Fl_Terminal::Utf8Char::text_ascii(char c, const CharStyle& style) {
// Signed char vals above 0x7f are /negative/, so <0x20 check covers those
if (c < 0x20 || c >= 0x7e) return; // ASCII non-printable?
if (c < 0x20 || c > 0x7e) return; // ASCII non-printable?
text_utf8(&c, 1, style);
}
@@ -733,7 +733,7 @@ void Fl_Terminal::RingBuffer::new_copy(int drows, int dcols, int hrows, const Ch
// Create new buffer
int addhist = disp_rows() - drows; // adjust history use
int new_ring_rows = (drows+hrows);
int new_hist_use = clamp(hist_use_ + addhist, 0, hrows); // clamp incase new_hist_rows smaller than old
int new_hist_use = clamp(hist_use_ + addhist, 0, hrows); // clamp in case new_hist_rows smaller than old
int new_nchars = (new_ring_rows * dcols);
Utf8Char *new_ring_chars = new Utf8Char[new_nchars]; // Create new ring buffer (†)
// Preserve old contents in new buffer
@@ -1023,8 +1023,8 @@ void Fl_Terminal::RingBuffer::create(int drows, int dcols, int hrows) {
// Resize the buffer, preserve previous contents as much as possible
void Fl_Terminal::RingBuffer::resize(int drows, int dcols, int hrows, const CharStyle& style) {
int new_rows = drows + hrows; // old display + history rows
int old_rows = disp_rows() + hist_rows(); // new display + history rows
int new_rows = drows + hrows; // new display + history rows
int old_rows = disp_rows() + hist_rows(); // old display + history rows
bool cols_changed = (dcols != disp_cols()); // was there a change in total #columns?
bool rows_changed = (new_rows != old_rows); // was there a change in total #rows?
// If rows or cols changed, make a NEW buffer and copy old contents.
@@ -1113,7 +1113,7 @@ Fl_Terminal::Utf8Char* Fl_Terminal::u8c_hist_row(int hrow)
of the scrollback history.
'hurow' is indexed relative to the beginning of the 'in use' part
of the scrollback history buffer. This may be a different from
of the scrollback history buffer. This may be different from
u8c_hist_row(int) if the history was recently cleared, and there
aren't many (or any) rows in the history buffer that have been
populated with scrollback text yet.
@@ -1123,7 +1123,7 @@ Fl_Terminal::Utf8Char* Fl_Terminal::u8c_hist_row(int hrow)
// Walk the entire screen history ("in use") and display to stdout
for (int row=0; row<hist_use(); row++) {
const Utf8Char *u8c = u8c_hist_use_row(row); // first char in row
for (int col=0; col<=hist_cols(); col++,u8c++) { // walk columns left-to-right
for (int col=0; col<hist_cols(); col++,u8c++) { // walk columns left-to-right
// ..Do things here with each u8c char..
::printf("%.*s", u8c->length(), u8c->text_utf8()); // show each utf8 char to stdout
}
@@ -1139,7 +1139,7 @@ Fl_Terminal::Utf8Char* Fl_Terminal::u8c_hist_use_row(int hurow)
/**
Return pointer to the first u8c character in row \p drow of the display.
- 'drow' is indexed relative to the beginning of the display buffer.
- This can be used to walk all columns in the specfied row, e.g.
- This can be used to walk all columns in the specified row, e.g.
\code
// Print all chars in first row of display (ASCII and UTF-8)
Utf8Char *u8c = u8c_disp_row(0); // first char of first display row
@@ -1156,9 +1156,9 @@ Fl_Terminal::Utf8Char* Fl_Terminal::u8c_hist_use_row(int hurow)
// Write all chars in display up to cursor row to stdout
for (int row=0; row<disp_rows() && row<=cursor_row(); row++) {
const Utf8Char *u8c = u8c_disp_row(row); // first char in row
for (int col=0; col<=display_cols(); col++,u8c++) { // walk columns left-to-right
for (int col=0; col<disp_cols(); col++,u8c++) { // walk columns left-to-right
// ..Do things here with each u8c char..
::printf("%.*s", u8c->text_utf8(), u8c->length()); // write each utf8 char to stdout
::printf("%.*s", u8c->length(), u8c->text_utf8()); // write each utf8 char to stdout
}
::printf("\n");
}
@@ -1224,12 +1224,10 @@ void Fl_Terminal::clear_all_tabstops(void) {
memset(tabstops_, 0, tabstops_size_);
}
// Set/clear tabstop at current cursor x position
// val: 0 clears tabstop, 1 sets tabstop
//
// Set tabstop at current cursor x position
void Fl_Terminal::set_tabstop(void) {
int index = clamp(cursor_col(), 0, tabstops_size_-1); // clamp cursor pos
tabstops_[index] = 1; // set/clr tabstop
tabstops_[index] = 1; // set tabstop
}
// Clear tabstop at current cursor x position
@@ -1365,7 +1363,7 @@ void Fl_Terminal::refit_disp_to_screen(void) {
if (below_cur) { // CASE 3: shrinking below cursor? drop lines below
ring_.disp_rows(display_rows() - 1); // effectively "deletes" lines below cursor
} else { // CASE 4: need to move cursor + lines up into hist
cursor_up(-1, false); // move cursor down to follow ring_.resize()
cursor_up(1, false); // move cursor up to follow ring_.resize()
// Handle shrinking ring's display up into history
ring_.resize(display_rows()-1, dcols, hist_rows(), *current_style_);
}
@@ -1491,7 +1489,7 @@ void Fl_Terminal::history_rows(int hrows) {
This value will be 0 if history was recently cleared with e.g.
clear_history() or \c "<ESC>c".
Return value will be in the range 0 .. (history_lines()-1).
Return value will be in the range 0 .. history_lines().
*/
int Fl_Terminal::history_use(void) const {
return ring_.hist_use();
@@ -1671,7 +1669,7 @@ void Fl_Terminal::textfgcolor_xterm(uchar val) {
/**
Sets the background text color as one of the 8 'xterm color' values.
This will be the foreground color used for all newly printed text,
This will be the background color used for all newly printed text,
similar to the \c \<ESC\>[\#m escape sequence, where \# is between 40 and 47.
This color will be reset to the default bg color if reset_terminal()
@@ -1707,7 +1705,7 @@ void Fl_Terminal::textbgcolor_xterm(uchar val) {
ensuring both are set to the same value.
Colors set this way will NOT be influenced by the xterm Dim/Bold color intensity attributes.
For that, use textcolor_xterm() instead.
For that, use textfgcolor_xterm() instead.
\see textfgcolor(Fl_Color), textfgcolor_default(Fl_Color), textbgcolor_xterm(uchar)
*/
@@ -1933,7 +1931,7 @@ void Fl_Terminal::clear_screen_home(bool scroll_to_hist) {
clear_screen(scroll_to_hist);
}
/// Clear from cursor to Start Of Display (EOD), like \c "<ESC>[1J".
/// Clear from cursor to Start Of Display (SOD), like \c "<ESC>[1J".
void Fl_Terminal::clear_sod(void) {
for (int drow=0; drow <= cursor_.row(); drow++)
if (drow == cursor_.row())
@@ -1945,7 +1943,7 @@ void Fl_Terminal::clear_sod(void) {
//TODO: Clear mouse selection?
}
/// Clear from cursor to End Of Display (EOD), like \c "<ESC>[J<ESC>[0J".
/// Clear from cursor to End Of Display (EOD), like \c "<ESC>[J" or "<ESC>[0J".
void Fl_Terminal::clear_eod(void) {
for (int drow=cursor_.row(); drow<disp_rows(); drow++)
if (drow == cursor_.row())
@@ -2036,7 +2034,7 @@ const Fl_Terminal::Utf8Char* Fl_Terminal::walk_selection(
/**
Return mouse selection's start/end position in the ring buffer, if any.
Ensures (start < end) to allow walking 'forward' thru selection,
Ensures (start <= end) to allow walking 'forward' thru selection,
left-to-right, top-to-bottom. The row/col values are indexes into
the entire ring buffer.
@@ -2051,7 +2049,7 @@ const Fl_Terminal::Utf8Char* Fl_Terminal::walk_selection(
for (int row=srow; row<=erow; row++) { // walk rows of selection
const Utf8Char *u8c = u8c_ring_row(row); // ptr to first character in row
int col_start = (row==srow) ? scol : 0; // start row? start at scol
int col_end = (row==erow) ? ecol : ring_cols(); // end row? end at ecol
int col_end = (row==erow) ? ecol : ring_cols()-1; // end row? end at ecol
u8c += col_start; // include col offset (if any)
for (int col=col_start; col<=col_end; col++,u8c++) { // walk columns
..do something with each char at *u8c..
@@ -2088,7 +2086,7 @@ bool Fl_Terminal::is_inside_selection(int grow, int gcol) const {
int check = (grow * ncols) + gcol;
int start = (select_.srow() * ncols) + select_.scol();
int end = (select_.erow() * ncols) + select_.ecol();
if (start > end) swap(start, end); // ensure (start < end)
if (start > end) swap(start, end); // ensure (start <= end)
return (check >= start && check <= end);
}
@@ -2393,7 +2391,7 @@ void Fl_Terminal::reset_terminal(void) {
//DEBUG }
//DEBUG // Show two buffers side-by-side on stdout.
//DEBUG // Second buffer can be NULL to just show the a buffer.
//DEBUG // Second buffer can be NULL to just show the A buffer.
//DEBUG //
//DEBUG void Fl_Terminal::show_buffers(RingBuffer *a, RingBuffer *b) const {
//DEBUG int arows = a->ring_rows(), acols = a->ring_cols();
@@ -2822,7 +2820,7 @@ void Fl_Terminal::handle_escseq(char c) {
cursor_cr();
cursor_up(escseq.defvalmax(1,dh));
break;
case 'G': // <ESC>[#G - (CHA) cursor horizal absolute
case 'G': // <ESC>[#G - (CHA) cursor horizontal absolute
switch (clamp(tot,0,1)) { // │
case 0: // ├── <ESC>[G -- move to sol
cursor_sol(); // │ default <ESC>[1G
@@ -2860,7 +2858,7 @@ cup:
break;
case 'J': // <ESC>[#J - (ED) erase in display
switch (clamp(tot,0,1)) { // │
case 0: clear_eol(); break; // ├── <ESC>[J -- no vals: default <ESC>[0J
case 0: clear_eod(); break; // ├── <ESC>[J -- no vals: default <ESC>[0J
case 1: // │
switch (clamp(val0,0,3)) { // │
case 0: clear_eod(); break; // ├── <ESC>[0J -- clear to end of display
@@ -3093,18 +3091,18 @@ void Fl_Terminal::plot_char(char c, int drow, int dcol) {
Handles control codes and can be used to construct ANSI/XTERM
escape sequences.
- If optional \p len isn't specified or <0, strlen(text) is used.
- If optional \p len isn't specified or <0, fl_utf8len1(*text) is used.
- \p text must not be NULL.
- \p len must not be 0.
- \p text must be a single char only (whether UTF-8 or ASCII)
- \p text can be an ASCII character, though not as efficent as print_char()
- \p text can be an ASCII character, though not as efficient as print_char()
- Invalid UTF-8 chars show the error character (¿) depending on show_unknown(bool).
- Does not trigger redraws
\see show_unknown(bool), handle_unknown_char()
*/
void Fl_Terminal::print_char(const char *text, int len/*=-1*/) {
len = len<0 ? fl_utf8len(*text) : len; // int(strlen(text)) : len;
len = len<0 ? fl_utf8len1(*text) : len;
const bool do_scroll = true;
if (is_ctrl(text[0])) { // Handle ctrl character
handle_ctrl(*text);
@@ -3153,7 +3151,7 @@ void Fl_Terminal::utf8_cache_flush(void) {
Append NULL terminated UTF-8 string to terminal.
- If buf is NULL, UTF-8 cache buffer is cleared
- If optional \p len isn't specified or is -1, strlen(text) is used.
- If optional \p len isn't specified or is -1, strlen(buf) is used.
- If \p len is 0 or <-1, no changes are made
- Handles UTF-8 chars split across calls (e.g. block writes from pipes, etc)
- Redraws are triggered automatically, depending on redraw_style()
@@ -3269,7 +3267,7 @@ void Fl_Terminal::append_ascii(const char *s) {
Fl::wait(0.05); // give fltk .05 secs of cpu to manage UI
ssize_t bytes = read(fd, s, sizeof(s)); // read block from pipe
if (bytes == -1 && errno == EAGAIN) continue; // no data yet? continue
if (bytes > 0) G_tty->append(s); // append output to terminal
if (bytes > 0) G_tty->append(s, bytes); // append output to terminal
else break; // end of pipe?
}
@@ -3425,7 +3423,7 @@ Fl_Terminal::Fl_Terminal(int X,int Y,int W,int H,const char*L)
the initial text buffer size based on the widget's pixel width/height, bypassing calls to
the font system before the widget is displayed.
\note fluid uses this constructor internally to avoid font calculations that opens
\note fluid uses this constructor internally to avoid font calculations that open
the display, useful for when running in a headless context. (issue 837)
*/
Fl_Terminal::Fl_Terminal(int X,int Y,int W,int H,const char*L,int rows,int cols,int hist)
@@ -3650,7 +3648,7 @@ void Fl_Terminal::draw_row(int grow, int Y) const {
int X = scrn_.x();
draw_row_bg(grow, X, Y);
// Draw forground text
// Draw foreground text
int baseline = Y + current_style_->fontheight() - current_style_->fontdescent();
int scrollval = scrollbar->value();
int disp_top = (disp_srow() - scrollval); // top row we need to view
@@ -3715,7 +3713,7 @@ void Fl_Terminal::draw_row(int grow, int Y) const {
Draws the buffer position we are scrolled to onto the FLTK screen
starting at pixel position Y.
This can be anywhere in the ring buffer, not just the 'active diplay';
This can be anywhere in the ring buffer, not just the 'active display';
depends on what position the scrollbar is set to.
Handles attributes, colors, text selections, cursor.
@@ -3999,7 +3997,7 @@ int Fl_Terminal::handle(int e) {
\param[in] lines_below_cursor include lines below cursor, default: false
\return A string allocated with strdup(3) which must be free'd, text is UTF-8.
\return A string allocated with strdup(3) which must be free()ed, text is UTF-8.
*/
const char* Fl_Terminal::text(bool lines_below_cursor) const {
std::string lines; // lines of text we'll return