|
|
@ -419,7 +419,10 @@ pfail: |
|
|
|
//////////////////////////////////////
|
|
|
|
//////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
// Ctor
|
|
|
|
// Ctor
|
|
|
|
Fl_Terminal::CharStyle::CharStyle(void) { |
|
|
|
// fontsize_defer - if true, hold off on doing fl_font() oriented calculations until
|
|
|
|
|
|
|
|
// just before draw(). This is for fluid's headless mode. (issue 837)
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
Fl_Terminal::CharStyle::CharStyle(bool fontsize_defer) { |
|
|
|
attrib_ = 0; |
|
|
|
attrib_ = 0; |
|
|
|
flags_ = 0; |
|
|
|
flags_ = 0; |
|
|
|
defaultfgcolor_ = 0xd0d0d000; // off white
|
|
|
|
defaultfgcolor_ = 0xd0d0d000; // off white
|
|
|
@ -429,7 +432,8 @@ Fl_Terminal::CharStyle::CharStyle(void) { |
|
|
|
flags_ |= (FG_XTERM | BG_XTERM); |
|
|
|
flags_ |= (FG_XTERM | BG_XTERM); |
|
|
|
fontface_ = FL_COURIER; |
|
|
|
fontface_ = FL_COURIER; |
|
|
|
fontsize_ = 14; |
|
|
|
fontsize_ = 14; |
|
|
|
update(); // updates fontheight_, fontdescent_, charwidth_
|
|
|
|
if (!fontsize_defer) update(); // normal behavior
|
|
|
|
|
|
|
|
else update_fake(); // use fake values instead
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Update fontheight/descent cache whenever font changes
|
|
|
|
// Update fontheight/descent cache whenever font changes
|
|
|
@ -441,6 +445,16 @@ void Fl_Terminal::CharStyle::update(void) { |
|
|
|
charwidth_ = int(fl_width("X") + 0.5); |
|
|
|
charwidth_ = int(fl_width("X") + 0.5); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Update fontheight/descent cache with fake values (issue 837)
|
|
|
|
|
|
|
|
// XXX: Please remove this issue 837 hack the minute fluid no longer has to
|
|
|
|
|
|
|
|
// instance fltk classes in headless mode
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
void Fl_Terminal::CharStyle::update_fake(void) { |
|
|
|
|
|
|
|
fontheight_ = 99; // Use fake values until first draw() when we call update() for real values.
|
|
|
|
|
|
|
|
fontdescent_ = 99; // Use absurdly large values here to make un-updated sizes clearly evident
|
|
|
|
|
|
|
|
charwidth_ = 99; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Return fg color
|
|
|
|
// Return fg color
|
|
|
|
Fl_Color Fl_Terminal::CharStyle::fgcolor(void) const { |
|
|
|
Fl_Color Fl_Terminal::CharStyle::fgcolor(void) const { |
|
|
|
return fgcolor_; |
|
|
|
return fgcolor_; |
|
|
@ -545,7 +559,7 @@ void Fl_Terminal::Utf8Char::text_utf8(const char *text, |
|
|
|
int len, |
|
|
|
int len, |
|
|
|
const CharStyle& style) { |
|
|
|
const CharStyle& style) { |
|
|
|
text_utf8_(text, len); // updates text_, len_
|
|
|
|
text_utf8_(text, len); // updates text_, len_
|
|
|
|
fl_font(style.fontface(), style.fontsize()); // need font to calc UTF-8 width
|
|
|
|
//issue 837 // fl_font(style.fontface(), style.fontsize()); // need font to calc UTF-8 width
|
|
|
|
attrib_ = style.attrib(); |
|
|
|
attrib_ = style.attrib(); |
|
|
|
flags_ = style.colorbits_only(flags_); |
|
|
|
flags_ = style.colorbits_only(flags_); |
|
|
|
fgcolor_ = style.fgcolor(); |
|
|
|
fgcolor_ = style.fgcolor(); |
|
|
@ -841,14 +855,14 @@ void Fl_Terminal::RingBuffer::scroll(int rows, const CharStyle& style) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Return UTF-8 char for 'row' in the ring
|
|
|
|
// Return UTF-8 char for 'row' in the ring
|
|
|
|
// Scrolling offset is NOT applied; this is raw access to the ring's rows.
|
|
|
|
// Scrolling offset is NOT applied; this is raw access to the ring's rows.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Example:
|
|
|
|
// Example:
|
|
|
|
// // Walk ALL rows in the ring buffer..
|
|
|
|
// // Walk ALL rows in the ring buffer..
|
|
|
|
// for (int row=0; row<ring.rows(); row++) {
|
|
|
|
// for (int row=0; row<ring.rows(); row++) {
|
|
|
|
// Utf8Char *u8c = ring.u8c_ring_row(row);
|
|
|
|
// Utf8Char *u8c = ring.u8c_ring_row(row);
|
|
|
|
// ..
|
|
|
|
// ..
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
//
|
|
|
|
const Fl_Terminal::Utf8Char* Fl_Terminal::RingBuffer::u8c_ring_row(int row) const { |
|
|
|
const Fl_Terminal::Utf8Char* Fl_Terminal::RingBuffer::u8c_ring_row(int row) const { |
|
|
|
row = normalize(row, ring_rows()); |
|
|
|
row = normalize(row, ring_rows()); |
|
|
@ -892,8 +906,8 @@ const Fl_Terminal::Utf8Char* Fl_Terminal::RingBuffer::u8c_hist_use_row(int hurow |
|
|
|
// Example:
|
|
|
|
// Example:
|
|
|
|
// // Walk ALL rows in display..
|
|
|
|
// // Walk ALL rows in display..
|
|
|
|
// for (int drow=0; drow<ring.drows(); drow++) {
|
|
|
|
// for (int drow=0; drow<ring.drows(); drow++) {
|
|
|
|
// Utf8Char *u8c = u8c_disp_row(drow);
|
|
|
|
// Utf8Char *u8c = u8c_disp_row(drow);
|
|
|
|
// ..
|
|
|
|
// ..
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
//
|
|
|
|
const Fl_Terminal::Utf8Char* Fl_Terminal::RingBuffer::u8c_disp_row(int drow) const { |
|
|
|
const Fl_Terminal::Utf8Char* Fl_Terminal::RingBuffer::u8c_disp_row(int drow) const { |
|
|
@ -903,7 +917,17 @@ const Fl_Terminal::Utf8Char* Fl_Terminal::RingBuffer::u8c_disp_row(int drow) con |
|
|
|
return &ring_chars_[rowi * ring_cols()]; |
|
|
|
return &ring_chars_[rowi * ring_cols()]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// non-const versions of the above
|
|
|
|
// non-const versions of the above ////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Return UTF-8 char for 'row' in the ring.
|
|
|
|
|
|
|
|
// Scrolling offset is NOT applied; this is raw access to the ring's rows.
|
|
|
|
|
|
|
|
// Example:
|
|
|
|
|
|
|
|
// // Walk ALL rows in the ring buffer..
|
|
|
|
|
|
|
|
// for (int row=0; row<ring.rows(); row++) {
|
|
|
|
|
|
|
|
// Utf8Char *u8c = ring.u8c_ring_row(row);
|
|
|
|
|
|
|
|
// ..
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
Fl_Terminal::Utf8Char* Fl_Terminal::RingBuffer::u8c_ring_row(int row) |
|
|
|
Fl_Terminal::Utf8Char* Fl_Terminal::RingBuffer::u8c_ring_row(int row) |
|
|
|
{ return const_cast<Utf8Char*>(const_cast<const RingBuffer*>(this)->u8c_ring_row(row)); } |
|
|
|
{ return const_cast<Utf8Char*>(const_cast<const RingBuffer*>(this)->u8c_ring_row(row)); } |
|
|
|
|
|
|
|
|
|
|
@ -913,6 +937,13 @@ Fl_Terminal::Utf8Char* Fl_Terminal::RingBuffer::u8c_hist_row(int hrow) |
|
|
|
Fl_Terminal::Utf8Char* Fl_Terminal::RingBuffer::u8c_hist_use_row(int hurow) |
|
|
|
Fl_Terminal::Utf8Char* Fl_Terminal::RingBuffer::u8c_hist_use_row(int hurow) |
|
|
|
{ return const_cast<Utf8Char*>(const_cast<const RingBuffer*>(this)->u8c_hist_use_row(hurow)); } |
|
|
|
{ return const_cast<Utf8Char*>(const_cast<const RingBuffer*>(this)->u8c_hist_use_row(hurow)); } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Return UTF-8 char for beginning of 'row' in the display buffer
|
|
|
|
|
|
|
|
// Example:
|
|
|
|
|
|
|
|
// // Walk ALL rows in display..
|
|
|
|
|
|
|
|
// for (int drow=0; drow<ring.drows(); drow++) {
|
|
|
|
|
|
|
|
// Utf8Char *u8c = u8c_disp_row(drow);
|
|
|
|
|
|
|
|
// ..
|
|
|
|
|
|
|
|
// }
|
|
|
|
Fl_Terminal::Utf8Char* Fl_Terminal::RingBuffer::u8c_disp_row(int drow) |
|
|
|
Fl_Terminal::Utf8Char* Fl_Terminal::RingBuffer::u8c_disp_row(int drow) |
|
|
|
{ return const_cast<Utf8Char*>(const_cast<const RingBuffer*>(this)->u8c_disp_row(drow)); } |
|
|
|
{ return const_cast<Utf8Char*>(const_cast<const RingBuffer*>(this)->u8c_disp_row(drow)); } |
|
|
|
|
|
|
|
|
|
|
@ -965,43 +996,87 @@ void Fl_Terminal::RingBuffer::change_disp_cols(int dcols, const CharStyle& style |
|
|
|
///// Fl_Terminal Class Methods /////
|
|
|
|
///// Fl_Terminal Class Methods /////
|
|
|
|
/////////////////////////////////////
|
|
|
|
/////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
// Return u8c for beginning of a row inside the ring.
|
|
|
|
/// See docs for non-const version of u8c_ring_row(int)
|
|
|
|
// 'grow' is 'globally' indexed (relative to the beginning of the ring buffer),
|
|
|
|
|
|
|
|
// and so can access ANY character in the entire ring buffer (hist or disp)
|
|
|
|
|
|
|
|
// by its global index, which is to say without any scrolling offset applied.
|
|
|
|
|
|
|
|
// Should really ONLY be used for making a complete copy of the ring.
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
const Fl_Terminal::Utf8Char* Fl_Terminal::u8c_ring_row(int grow) const |
|
|
|
const Fl_Terminal::Utf8Char* Fl_Terminal::u8c_ring_row(int grow) const |
|
|
|
{ return ring_.u8c_ring_row(grow); } |
|
|
|
{ return ring_.u8c_ring_row(grow); } |
|
|
|
|
|
|
|
|
|
|
|
// Return u8c for beginning of a row inside the history.
|
|
|
|
/// See docs for non-const version of u8c_hist_row(int)
|
|
|
|
// 'hrow' is indexed relative to the beginning of the history buffer.
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
const Fl_Terminal::Utf8Char* Fl_Terminal::u8c_hist_row(int hrow) const |
|
|
|
const Fl_Terminal::Utf8Char* Fl_Terminal::u8c_hist_row(int hrow) const |
|
|
|
{ return ring_.u8c_hist_row(hrow); } |
|
|
|
{ return ring_.u8c_hist_row(hrow); } |
|
|
|
|
|
|
|
|
|
|
|
// Return u8c for beginning of a row inside the 'in use' history.
|
|
|
|
/// See docs for non-const version of u8c_hist_use_row(int)
|
|
|
|
// 'hurow' is indexed relative to the beginning of the 'in use' buffer.
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
const Fl_Terminal::Utf8Char* Fl_Terminal::u8c_hist_use_row(int hurow) const |
|
|
|
const Fl_Terminal::Utf8Char* Fl_Terminal::u8c_hist_use_row(int hurow) const |
|
|
|
{ return ring_.u8c_hist_use_row(hurow); } |
|
|
|
{ return ring_.u8c_hist_use_row(hurow); } |
|
|
|
|
|
|
|
|
|
|
|
// Return u8c for beginning of a row inside the display
|
|
|
|
/// See docs for non-const version of u8c_disp_row(int)
|
|
|
|
// 'drow' is indexed relative to the beginning of the display buffer.
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
const Fl_Terminal::Utf8Char* Fl_Terminal::u8c_disp_row(int drow) const |
|
|
|
const Fl_Terminal::Utf8Char* Fl_Terminal::u8c_disp_row(int drow) const |
|
|
|
{ return ring_.u8c_disp_row(drow); } |
|
|
|
{ return ring_.u8c_disp_row(drow); } |
|
|
|
|
|
|
|
|
|
|
|
// non-const versions of the above
|
|
|
|
// non-const versions of the above ////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
Return UTF-8 char for row \p grow in the ring buffer. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\p grow is globally indexed relative to the beginning of the ring buffer, |
|
|
|
|
|
|
|
so this method can access ANY character in the entire ring buffer (hist or disp) |
|
|
|
|
|
|
|
by the global index. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Scrolling offset is NOT applied; this is raw access to the ring's rows. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Should really ONLY be used for making a complete copy of the ring. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Example: |
|
|
|
|
|
|
|
\code |
|
|
|
|
|
|
|
// Walk ALL rows and cols in the ring buffer..
|
|
|
|
|
|
|
|
for (int row=0; row<ring.rows(); row++) { |
|
|
|
|
|
|
|
Utf8Char *u8c = ring.u8c_ring_row(row); |
|
|
|
|
|
|
|
for (int col=0; col<ring.cols(); col++,u8c++) { |
|
|
|
|
|
|
|
..make use of u8c->xxx() methods.. |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
\endcode |
|
|
|
|
|
|
|
*/ |
|
|
|
Fl_Terminal::Utf8Char* Fl_Terminal::u8c_ring_row(int grow) |
|
|
|
Fl_Terminal::Utf8Char* Fl_Terminal::u8c_ring_row(int grow) |
|
|
|
{ return const_cast<Utf8Char*>(const_cast<const Fl_Terminal*>(this)->u8c_ring_row(grow)); } |
|
|
|
{ return const_cast<Utf8Char*>(const_cast<const Fl_Terminal*>(this)->u8c_ring_row(grow)); } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
Return u8c for beginning of a row inside the scrollback history. |
|
|
|
|
|
|
|
'hrow' is indexed relative to the beginning of the scrollback history buffer. |
|
|
|
|
|
|
|
\see u8c_disp_row(int) for example use. |
|
|
|
|
|
|
|
*/ |
|
|
|
Fl_Terminal::Utf8Char* Fl_Terminal::u8c_hist_row(int hrow) |
|
|
|
Fl_Terminal::Utf8Char* Fl_Terminal::u8c_hist_row(int hrow) |
|
|
|
{ return const_cast<Utf8Char*>(const_cast<const Fl_Terminal*>(this)->u8c_hist_row(hrow)); } |
|
|
|
{ return const_cast<Utf8Char*>(const_cast<const Fl_Terminal*>(this)->u8c_hist_row(hrow)); } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
Return u8c for beginning of row \p hurow inside the 'in use' part |
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
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. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\see u8c_disp_row(int) for example use. |
|
|
|
|
|
|
|
*/ |
|
|
|
Fl_Terminal::Utf8Char* Fl_Terminal::u8c_hist_use_row(int hurow) |
|
|
|
Fl_Terminal::Utf8Char* Fl_Terminal::u8c_hist_use_row(int hurow) |
|
|
|
{ return const_cast<Utf8Char*>(const_cast<const Fl_Terminal*>(this)->u8c_hist_use_row(hurow)); } |
|
|
|
{ return const_cast<Utf8Char*>(const_cast<const Fl_Terminal*>(this)->u8c_hist_use_row(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. |
|
|
|
|
|
|
|
\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
|
|
|
|
|
|
|
|
int scol = 0, ecol = disp_cols(); // start/end for column loop
|
|
|
|
|
|
|
|
for (int col=scol; col<ecol; col++,u8c++) { // loop from first char to last
|
|
|
|
|
|
|
|
char *text = u8c->text_utf8(); // text string for char
|
|
|
|
|
|
|
|
int len = u8c->length(); // text string length for char
|
|
|
|
|
|
|
|
::printf("<%.*s>", len, text); // print potentially multibyte char
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
\endcode |
|
|
|
|
|
|
|
*/ |
|
|
|
Fl_Terminal::Utf8Char* Fl_Terminal::u8c_disp_row(int drow) |
|
|
|
Fl_Terminal::Utf8Char* Fl_Terminal::u8c_disp_row(int drow) |
|
|
|
{ return const_cast<Utf8Char*>(const_cast<const Fl_Terminal*>(this)->u8c_disp_row(drow)); } |
|
|
|
{ return const_cast<Utf8Char*>(const_cast<const Fl_Terminal*>(this)->u8c_disp_row(drow)); } |
|
|
|
|
|
|
|
|
|
|
@ -1023,6 +1098,11 @@ void Fl_Terminal::create_ring(int drows, int dcols, int hrows) { |
|
|
|
cursor_.home(); |
|
|
|
cursor_.home(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Return the Utf8Char* for character under cursor.
|
|
|
|
|
|
|
|
Fl_Terminal::Utf8Char* Fl_Terminal::u8c_cursor(void) { |
|
|
|
|
|
|
|
return u8c_disp_row(cursor_.row()) + cursor_.col(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Return scrollbar width if visible, or 0 if not visible.
|
|
|
|
/// Return scrollbar width if visible, or 0 if not visible.
|
|
|
|
int Fl_Terminal::vscroll_width(void) const { |
|
|
|
int Fl_Terminal::vscroll_width(void) const { |
|
|
|
return(vscroll_->visible() ? vscroll_->w() : 0); |
|
|
|
return(vscroll_->visible() ? vscroll_->w() : 0); |
|
|
@ -1116,7 +1196,7 @@ void Fl_Terminal::refit_disp_to_screen(void) { |
|
|
|
int drows = clamp(dh, 2, dh); // 2 rows minimum
|
|
|
|
int drows = clamp(dh, 2, dh); // 2 rows minimum
|
|
|
|
int dcols = clamp(dw, 10, dw); // 10 cols minimum
|
|
|
|
int dcols = clamp(dw, 10, dw); // 10 cols minimum
|
|
|
|
int drow_diff = drows - ring_.disp_rows(); // change in rows?
|
|
|
|
int drow_diff = drows - ring_.disp_rows(); // change in rows?
|
|
|
|
ring_.resize(drows, dcols, hist_rows(), current_style_); |
|
|
|
ring_.resize(drows, dcols, hist_rows(), *current_style_); |
|
|
|
cursor_.scroll(-drow_diff); |
|
|
|
cursor_.scroll(-drow_diff); |
|
|
|
clear_mouse_selection(); |
|
|
|
clear_mouse_selection(); |
|
|
|
update_screen(false); |
|
|
|
update_screen(false); |
|
|
@ -1160,7 +1240,7 @@ void Fl_Terminal::resize_display_rows(int drows) { |
|
|
|
int new_dcols = ring_cols(); // keep cols the same
|
|
|
|
int new_dcols = ring_cols(); // keep cols the same
|
|
|
|
int new_hrows = hist_rows() - drow_diff; // keep disp:hist ratio same
|
|
|
|
int new_hrows = hist_rows() - drow_diff; // keep disp:hist ratio same
|
|
|
|
if (new_hrows<0) new_hrows = 0; // don't let hist be <0
|
|
|
|
if (new_hrows<0) new_hrows = 0; // don't let hist be <0
|
|
|
|
ring_.resize(drows, new_dcols, new_hrows, current_style_); |
|
|
|
ring_.resize(drows, new_dcols, new_hrows, *current_style_); |
|
|
|
// ..update cursor/selections to track text position
|
|
|
|
// ..update cursor/selections to track text position
|
|
|
|
cursor_.scroll(-drow_diff); |
|
|
|
cursor_.scroll(-drow_diff); |
|
|
|
select_.clear(); // clear any mouse selection
|
|
|
|
select_.clear(); // clear any mouse selection
|
|
|
@ -1177,7 +1257,7 @@ void Fl_Terminal::resize_display_columns(int dcols) { |
|
|
|
// No changes? early exit
|
|
|
|
// No changes? early exit
|
|
|
|
if (dcols == disp_cols()) return; |
|
|
|
if (dcols == disp_cols()) return; |
|
|
|
// Change cols, preserves previous content if possible
|
|
|
|
// Change cols, preserves previous content if possible
|
|
|
|
ring_.resize(disp_rows(), dcols, hist_rows(), current_style_); |
|
|
|
ring_.resize(disp_rows(), dcols, hist_rows(), *current_style_); |
|
|
|
update_scrollbar(); |
|
|
|
update_scrollbar(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1200,8 +1280,11 @@ void Fl_Terminal::update_screen(bool font_changed) { |
|
|
|
// current_style: update cursor's size for current font/size
|
|
|
|
// current_style: update cursor's size for current font/size
|
|
|
|
if (font_changed) { |
|
|
|
if (font_changed) { |
|
|
|
// Change font and current_style's font height
|
|
|
|
// Change font and current_style's font height
|
|
|
|
fl_font(current_style_.fontface(), current_style_.fontsize()); |
|
|
|
if (!fontsize_defer_) { // issue 837
|
|
|
|
cursor_.h(current_style_.fontheight()); |
|
|
|
//DEBUG fprintf(stderr, "update_screen(font change): row/cols=%d/%d, cs.width=%d, cs.height=%d\n", display_rows(), display_columns(), current_style_->charwidth(), current_style_->fontheight());
|
|
|
|
|
|
|
|
fl_font(current_style_->fontface(), current_style_->fontsize()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
cursor_.h(current_style_->fontheight()); |
|
|
|
} |
|
|
|
} |
|
|
|
// Update the scrn_* values
|
|
|
|
// Update the scrn_* values
|
|
|
|
update_screen_xywh(); |
|
|
|
update_screen_xywh(); |
|
|
@ -1221,7 +1304,7 @@ int Fl_Terminal::history_rows(void) const { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void Fl_Terminal::history_rows(int hrows) { |
|
|
|
void Fl_Terminal::history_rows(int hrows) { |
|
|
|
if (hrows == history_rows()) return; // no change? done
|
|
|
|
if (hrows == history_rows()) return; // no change? done
|
|
|
|
ring_.resize(disp_rows(), disp_cols(), hrows, current_style_); |
|
|
|
ring_.resize(disp_rows(), disp_cols(), hrows, *current_style_); |
|
|
|
update_screen(false); // false: no font change
|
|
|
|
update_screen(false); // false: no font change
|
|
|
|
display_modified(); |
|
|
|
display_modified(); |
|
|
|
} |
|
|
|
} |
|
|
@ -1258,7 +1341,7 @@ int Fl_Terminal::display_rows(void) const { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void Fl_Terminal::display_rows(int drows) { |
|
|
|
void Fl_Terminal::display_rows(int drows) { |
|
|
|
if (drows == disp_rows()) return; // no change? early exit
|
|
|
|
if (drows == disp_rows()) return; // no change? early exit
|
|
|
|
ring_.resize(drows, disp_cols(), hist_rows(), current_style_); |
|
|
|
ring_.resize(drows, disp_cols(), hist_rows(), *current_style_); |
|
|
|
update_screen(false); // false: no font change ?NEED?
|
|
|
|
update_screen(false); // false: no font change ?NEED?
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1289,18 +1372,18 @@ int Fl_Terminal::display_columns(void) const { |
|
|
|
void Fl_Terminal::display_columns(int dcols) { |
|
|
|
void Fl_Terminal::display_columns(int dcols) { |
|
|
|
if (dcols == disp_cols()) return; // no change? early exit
|
|
|
|
if (dcols == disp_cols()) return; // no change? early exit
|
|
|
|
// Change cols, preserves previous content if possible
|
|
|
|
// Change cols, preserves previous content if possible
|
|
|
|
ring_.resize(disp_rows(), dcols, hist_rows(), current_style_); |
|
|
|
ring_.resize(disp_rows(), dcols, hist_rows(), *current_style_); |
|
|
|
update_screen(false); // false: no font change ?NEED?
|
|
|
|
update_screen(false); // false: no font change ?NEED?
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** Return current style for rendering text. */ |
|
|
|
/** Return current style for rendering text. */ |
|
|
|
const Fl_Terminal::CharStyle& Fl_Terminal::current_style(void) const { |
|
|
|
const Fl_Terminal::CharStyle& Fl_Terminal::current_style(void) const { |
|
|
|
return current_style_; |
|
|
|
return *current_style_; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** Set current style for rendering text. */ |
|
|
|
/** Set current style for rendering text. */ |
|
|
|
void Fl_Terminal::current_style(const CharStyle& sty) { |
|
|
|
void Fl_Terminal::current_style(const CharStyle& sty) { |
|
|
|
current_style_ = sty; |
|
|
|
*current_style_ = sty; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -1354,7 +1437,7 @@ void Fl_Terminal::margin_bottom(int val) { |
|
|
|
as they are monospace. |
|
|
|
as they are monospace. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void Fl_Terminal::textfont(Fl_Font val) { |
|
|
|
void Fl_Terminal::textfont(Fl_Font val) { |
|
|
|
current_style_.fontface(val); |
|
|
|
current_style_->fontface(val); |
|
|
|
update_screen(true); |
|
|
|
update_screen(true); |
|
|
|
display_modified(); |
|
|
|
display_modified(); |
|
|
|
} |
|
|
|
} |
|
|
@ -1368,7 +1451,7 @@ void Fl_Terminal::textfont(Fl_Font val) { |
|
|
|
Changing this will affect the display_rows() and display_columns(). |
|
|
|
Changing this will affect the display_rows() and display_columns(). |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void Fl_Terminal::textsize(Fl_Fontsize val) { |
|
|
|
void Fl_Terminal::textsize(Fl_Fontsize val) { |
|
|
|
current_style_.fontsize(val); |
|
|
|
current_style_->fontsize(val); |
|
|
|
update_screen(true); |
|
|
|
update_screen(true); |
|
|
|
// Changing font size affects #lines in display, so resize it
|
|
|
|
// Changing font size affects #lines in display, so resize it
|
|
|
|
refit_disp_to_screen(); |
|
|
|
refit_disp_to_screen(); |
|
|
@ -1404,7 +1487,7 @@ void Fl_Terminal::textsize(Fl_Fontsize val) { |
|
|
|
\see textfgcolor_default(Fl_Color) |
|
|
|
\see textfgcolor_default(Fl_Color) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void Fl_Terminal::textfgcolor_xterm(uchar val) { |
|
|
|
void Fl_Terminal::textfgcolor_xterm(uchar val) { |
|
|
|
current_style_.fgcolor(fltk_fg_color(val)); |
|
|
|
current_style_->fgcolor(fltk_fg_color(val)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -1436,7 +1519,7 @@ void Fl_Terminal::textfgcolor_xterm(uchar val) { |
|
|
|
\see textbgcolor_default(Fl_Color) |
|
|
|
\see textbgcolor_default(Fl_Color) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void Fl_Terminal::textbgcolor_xterm(uchar val) { |
|
|
|
void Fl_Terminal::textbgcolor_xterm(uchar val) { |
|
|
|
current_style_.bgcolor(fltk_bg_color(val)); |
|
|
|
current_style_->bgcolor(fltk_bg_color(val)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -1485,7 +1568,7 @@ void Fl_Terminal::color(Fl_Color val) { |
|
|
|
\see textfgcolor_default(Fl_Color) |
|
|
|
\see textfgcolor_default(Fl_Color) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void Fl_Terminal::textfgcolor(Fl_Color val) { |
|
|
|
void Fl_Terminal::textfgcolor(Fl_Color val) { |
|
|
|
current_style_.fgcolor(val); |
|
|
|
current_style_->fgcolor(val); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -1509,7 +1592,7 @@ void Fl_Terminal::textfgcolor(Fl_Color val) { |
|
|
|
\see textbgcolor_default(Fl_Color) |
|
|
|
\see textbgcolor_default(Fl_Color) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void Fl_Terminal::textbgcolor(Fl_Color val) { |
|
|
|
void Fl_Terminal::textbgcolor(Fl_Color val) { |
|
|
|
current_style_.bgcolor(val); |
|
|
|
current_style_->bgcolor(val); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -1521,7 +1604,7 @@ void Fl_Terminal::textbgcolor(Fl_Color val) { |
|
|
|
\see textfgcolor(Fl_Color) |
|
|
|
\see textfgcolor(Fl_Color) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void Fl_Terminal::textfgcolor_default(Fl_Color val) { |
|
|
|
void Fl_Terminal::textfgcolor_default(Fl_Color val) { |
|
|
|
current_style_.defaultfgcolor(val); |
|
|
|
current_style_->defaultfgcolor(val); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -1537,7 +1620,7 @@ void Fl_Terminal::textfgcolor_default(Fl_Color val) { |
|
|
|
\see textbgcolor(Fl_Color) |
|
|
|
\see textbgcolor(Fl_Color) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void Fl_Terminal::textbgcolor_default(Fl_Color val) { |
|
|
|
void Fl_Terminal::textbgcolor_default(Fl_Color val) { |
|
|
|
current_style_.defaultbgcolor(val); |
|
|
|
current_style_->defaultbgcolor(val); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -1547,7 +1630,7 @@ void Fl_Terminal::textbgcolor_default(Fl_Color val) { |
|
|
|
\see Fl_Terminal::Attrib |
|
|
|
\see Fl_Terminal::Attrib |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void Fl_Terminal::textattrib(uchar val) { |
|
|
|
void Fl_Terminal::textattrib(uchar val) { |
|
|
|
current_style_.attrib(val); |
|
|
|
current_style_->attrib(val); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -1560,7 +1643,7 @@ int Fl_Terminal::x_to_glob_col(int X, int grow, int &gcol) const { |
|
|
|
int cx = x() + margin_.left(); // char x position
|
|
|
|
int cx = x() + margin_.left(); // char x position
|
|
|
|
const Utf8Char *u8c = utf8_char_at_glob(grow, 0); |
|
|
|
const Utf8Char *u8c = utf8_char_at_glob(grow, 0); |
|
|
|
for (gcol=0; gcol<ring_cols(); gcol++,u8c++) { // walk the cols looking for X
|
|
|
|
for (gcol=0; gcol<ring_cols(); gcol++,u8c++) { // walk the cols looking for X
|
|
|
|
u8c->fl_font_set(current_style_); // pwidth_int() needs fl_font set
|
|
|
|
u8c->fl_font_set(*current_style_); // pwidth_int() needs fl_font set
|
|
|
|
int cx2 = cx + u8c->pwidth_int(); // char x2 (right edge of char)
|
|
|
|
int cx2 = cx + u8c->pwidth_int(); // char x2 (right edge of char)
|
|
|
|
if (X >= cx && X < cx2) return 1; // found? return with gcol set
|
|
|
|
if (X >= cx && X < cx2) return 1; // found? return with gcol set
|
|
|
|
cx += u8c->pwidth_int(); // move cx to start x of next char
|
|
|
|
cx += u8c->pwidth_int(); // move cx to start x of next char
|
|
|
@ -1584,7 +1667,7 @@ int Fl_Terminal::xy_to_glob_rowcol(int X, int Y, int &grow, int &gcol) const { |
|
|
|
// Find toprow of what's currently drawn on screen
|
|
|
|
// Find toprow of what's currently drawn on screen
|
|
|
|
int toprow = disp_srow() - vscroll_->value(); |
|
|
|
int toprow = disp_srow() - vscroll_->value(); |
|
|
|
// Find row the 'Y' value is in
|
|
|
|
// Find row the 'Y' value is in
|
|
|
|
grow = toprow + ( (Y-scrn_.y()) / current_style_.fontheight()); |
|
|
|
grow = toprow + ( (Y-scrn_.y()) / current_style_->fontheight()); |
|
|
|
return x_to_glob_col(X, grow, gcol); |
|
|
|
return x_to_glob_col(X, grow, gcol); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1676,7 +1759,7 @@ void Fl_Terminal::clear_eod(void) { |
|
|
|
void Fl_Terminal::clear_eol(void) { |
|
|
|
void Fl_Terminal::clear_eol(void) { |
|
|
|
Utf8Char *u8c = u8c_disp_row(cursor_.row()) + cursor_.col(); // start at cursor
|
|
|
|
Utf8Char *u8c = u8c_disp_row(cursor_.row()) + cursor_.col(); // start at cursor
|
|
|
|
for (int col=cursor_.col(); col<disp_cols(); col++) // run from cursor to eol
|
|
|
|
for (int col=cursor_.col(); col<disp_cols(); col++) // run from cursor to eol
|
|
|
|
(u8c++)->clear(current_style_); |
|
|
|
(u8c++)->clear(*current_style_); |
|
|
|
//TODO: Clear mouse selection?
|
|
|
|
//TODO: Clear mouse selection?
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1684,7 +1767,7 @@ void Fl_Terminal::clear_eol(void) { |
|
|
|
void Fl_Terminal::clear_sol(void) { |
|
|
|
void Fl_Terminal::clear_sol(void) { |
|
|
|
Utf8Char *u8c = u8c_disp_row(cursor_.row()); // start at sol
|
|
|
|
Utf8Char *u8c = u8c_disp_row(cursor_.row()); // start at sol
|
|
|
|
for (int col=0; col<=cursor_.col(); col++) // run from sol to cursor
|
|
|
|
for (int col=0; col<=cursor_.col(); col++) // run from sol to cursor
|
|
|
|
(u8c++)->clear(current_style_); |
|
|
|
(u8c++)->clear(*current_style_); |
|
|
|
//TODO: Clear mouse selection?
|
|
|
|
//TODO: Clear mouse selection?
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1692,7 +1775,7 @@ void Fl_Terminal::clear_sol(void) { |
|
|
|
void Fl_Terminal::clear_line(int drow) { |
|
|
|
void Fl_Terminal::clear_line(int drow) { |
|
|
|
Utf8Char *u8c = u8c_disp_row(drow); // start at sol
|
|
|
|
Utf8Char *u8c = u8c_disp_row(drow); // start at sol
|
|
|
|
for (int col=0; col<disp_cols(); col++) // run to eol
|
|
|
|
for (int col=0; col<disp_cols(); col++) // run to eol
|
|
|
|
(u8c++)->clear(current_style_); |
|
|
|
(u8c++)->clear(*current_style_); |
|
|
|
//TODO: Clear mouse selection?
|
|
|
|
//TODO: Clear mouse selection?
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1908,7 +1991,7 @@ bool Fl_Terminal::selection_extend(int X,int Y) { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void Fl_Terminal::scroll(int rows) { |
|
|
|
void Fl_Terminal::scroll(int rows) { |
|
|
|
// Scroll the ring
|
|
|
|
// Scroll the ring
|
|
|
|
ring_.scroll(rows, current_style_); |
|
|
|
ring_.scroll(rows, *current_style_); |
|
|
|
if (rows > 0) update_scrollbar(); // scroll up? changes hist, so scrollbar affected
|
|
|
|
if (rows > 0) update_scrollbar(); // scroll up? changes hist, so scrollbar affected
|
|
|
|
else clear_mouse_selection(); // scroll dn? clear mouse select; it might wrap ring
|
|
|
|
else clear_mouse_selection(); // scroll dn? clear mouse select; it might wrap ring
|
|
|
|
} |
|
|
|
} |
|
|
@ -1930,7 +2013,7 @@ void Fl_Terminal::insert_rows(int count) { |
|
|
|
while ( dst_drow >= cursor_.row() ) { // walk srcrow to curs line
|
|
|
|
while ( dst_drow >= cursor_.row() ) { // walk srcrow to curs line
|
|
|
|
Utf8Char *dst = u8c_disp_row(dst_drow--); |
|
|
|
Utf8Char *dst = u8c_disp_row(dst_drow--); |
|
|
|
for (int dcol=0; dcol<disp_cols(); dcol++) |
|
|
|
for (int dcol=0; dcol<disp_cols(); dcol++) |
|
|
|
dst++->clear(current_style_); |
|
|
|
dst++->clear(*current_style_); |
|
|
|
} |
|
|
|
} |
|
|
|
clear_mouse_selection(); |
|
|
|
clear_mouse_selection(); |
|
|
|
} |
|
|
|
} |
|
|
@ -1953,7 +2036,7 @@ void Fl_Terminal::delete_rows(int count) { |
|
|
|
while ( dst_drow < disp_rows() ) { // walk srcrow to EOD
|
|
|
|
while ( dst_drow < disp_rows() ) { // walk srcrow to EOD
|
|
|
|
Utf8Char *dst = u8c_disp_row(dst_drow++); |
|
|
|
Utf8Char *dst = u8c_disp_row(dst_drow++); |
|
|
|
for (int dcol=0; dcol<disp_cols(); dcol++) |
|
|
|
for (int dcol=0; dcol<disp_cols(); dcol++) |
|
|
|
dst++->clear(current_style_); |
|
|
|
dst++->clear(*current_style_); |
|
|
|
} |
|
|
|
} |
|
|
|
clear_mouse_selection(); |
|
|
|
clear_mouse_selection(); |
|
|
|
} |
|
|
|
} |
|
|
@ -1981,7 +2064,7 @@ void Fl_Terminal::insert_char_eol(char c, int drow, int dcol, int rep) { |
|
|
|
//
|
|
|
|
//
|
|
|
|
rep = clamp(rep, 0, disp_cols()); // sanity
|
|
|
|
rep = clamp(rep, 0, disp_cols()); // sanity
|
|
|
|
if (rep == 0) return; |
|
|
|
if (rep == 0) return; |
|
|
|
const CharStyle &style = current_style_; |
|
|
|
const CharStyle &style = *current_style_; |
|
|
|
Utf8Char *src = u8c_disp_row(drow)+disp_cols()-1-rep; // start src at 'g'
|
|
|
|
Utf8Char *src = u8c_disp_row(drow)+disp_cols()-1-rep; // start src at 'g'
|
|
|
|
Utf8Char *dst = u8c_disp_row(drow)+disp_cols()-1; // start dst at 'j'
|
|
|
|
Utf8Char *dst = u8c_disp_row(drow)+disp_cols()-1; // start dst at 'j'
|
|
|
|
for (int col=(disp_cols()-1); col>=dcol; col--) { // loop col in reverse: eol -> dcol
|
|
|
|
for (int col=(disp_cols()-1); col>=dcol; col--) { // loop col in reverse: eol -> dcol
|
|
|
@ -2002,7 +2085,7 @@ void Fl_Terminal::insert_char(char c, int rep) { |
|
|
|
void Fl_Terminal::delete_chars(int drow, int dcol, int rep) { |
|
|
|
void Fl_Terminal::delete_chars(int drow, int dcol, int rep) { |
|
|
|
rep = clamp(rep, 0, disp_cols()); // sanity
|
|
|
|
rep = clamp(rep, 0, disp_cols()); // sanity
|
|
|
|
if (rep == 0) return; |
|
|
|
if (rep == 0) return; |
|
|
|
const CharStyle &style = current_style_; |
|
|
|
const CharStyle &style = *current_style_; |
|
|
|
Utf8Char *u8c = u8c_disp_row(drow); |
|
|
|
Utf8Char *u8c = u8c_disp_row(drow); |
|
|
|
for (int col=dcol; col<disp_cols(); col++) // delete left-to-right
|
|
|
|
for (int col=dcol; col<disp_cols(); col++) // delete left-to-right
|
|
|
|
if (col+rep >= disp_cols()) u8c[col].text_ascii(' ', style); // blanks
|
|
|
|
if (col+rep >= disp_cols()) u8c[col].text_ascii(' ', style); // blanks
|
|
|
@ -2026,7 +2109,7 @@ void Fl_Terminal::clear_history(void) { |
|
|
|
for (int hrow=0; hrow<hist_rows(); hrow++) { |
|
|
|
for (int hrow=0; hrow<hist_rows(); hrow++) { |
|
|
|
Utf8Char *u8c = u8c_hist_row(hrow); // walk history rows..
|
|
|
|
Utf8Char *u8c = u8c_hist_row(hrow); // walk history rows..
|
|
|
|
for (int hcol=0; hcol<hist_cols(); hcol++) { // ..and history cols
|
|
|
|
for (int hcol=0; hcol<hist_cols(); hcol++) { // ..and history cols
|
|
|
|
(u8c++)->clear(current_style_); |
|
|
|
(u8c++)->clear(*current_style_); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// Adjust scrollbar (hist_use changed)
|
|
|
|
// Adjust scrollbar (hist_use changed)
|
|
|
@ -2038,7 +2121,7 @@ void Fl_Terminal::clear_history(void) { |
|
|
|
mouse selection, homes cursor, resets tabstops. Same as \c "<ESC>c" |
|
|
|
mouse selection, homes cursor, resets tabstops. Same as \c "<ESC>c" |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void Fl_Terminal::reset_terminal(void) { |
|
|
|
void Fl_Terminal::reset_terminal(void) { |
|
|
|
current_style_.sgr_reset(); // reset current style
|
|
|
|
current_style_->sgr_reset(); // reset current style
|
|
|
|
clear_screen_home(); // clear screen, home cursor
|
|
|
|
clear_screen_home(); // clear screen, home cursor
|
|
|
|
clear_history(); |
|
|
|
clear_history(); |
|
|
|
clear_mouse_selection(); |
|
|
|
clear_mouse_selection(); |
|
|
@ -2302,7 +2385,7 @@ void Fl_Terminal::handle_SGR(void) { // ESC[...m? |
|
|
|
int tot = esc.total_vals(); |
|
|
|
int tot = esc.total_vals(); |
|
|
|
// Handle ESC[m or ESC[;m
|
|
|
|
// Handle ESC[m or ESC[;m
|
|
|
|
if (tot == 0) |
|
|
|
if (tot == 0) |
|
|
|
{ current_style_.sgr_reset(); return; } |
|
|
|
{ current_style_->sgr_reset(); return; } |
|
|
|
// Handle ESC[#;#;#...m
|
|
|
|
// Handle ESC[#;#;#...m
|
|
|
|
int rgbcode = 0; // 0=none, 38=fg, 48=bg
|
|
|
|
int rgbcode = 0; // 0=none, 38=fg, 48=bg
|
|
|
|
int rgbmode = 0; // 0=none, 1="2", 2=<r>, 3=<g>, 4=<b>
|
|
|
|
int rgbmode = 0; // 0=none, 1="2", 2=<r>, 3=<g>, 4=<b>
|
|
|
@ -2328,9 +2411,9 @@ void Fl_Terminal::handle_SGR(void) { // ESC[...m? |
|
|
|
case 3: g=clamp(val,0,255); ++rgbmode; continue; // parse grn value
|
|
|
|
case 3: g=clamp(val,0,255); ++rgbmode; continue; // parse grn value
|
|
|
|
case 4: b=clamp(val,0,255); // parse blu value
|
|
|
|
case 4: b=clamp(val,0,255); // parse blu value
|
|
|
|
switch (rgbcode) { |
|
|
|
switch (rgbcode) { |
|
|
|
case 38: current_style_.fgcolor(r,g,b); // Set fg rgb
|
|
|
|
case 38: current_style_->fgcolor(r,g,b); // Set fg rgb
|
|
|
|
break; |
|
|
|
break; |
|
|
|
case 48: current_style_.bgcolor(r,g,b); // Set bg rgb
|
|
|
|
case 48: current_style_->bgcolor(r,g,b); // Set bg rgb
|
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
rgbcode = rgbmode = 0; // done w/rgb mode parsing
|
|
|
|
rgbcode = rgbmode = 0; // done w/rgb mode parsing
|
|
|
@ -2338,42 +2421,42 @@ void Fl_Terminal::handle_SGR(void) { // ESC[...m? |
|
|
|
} |
|
|
|
} |
|
|
|
if (val < 10) { // Set attribute? (bold,underline..)
|
|
|
|
if (val < 10) { // Set attribute? (bold,underline..)
|
|
|
|
switch ( val ) { |
|
|
|
switch ( val ) { |
|
|
|
case 0: current_style_.sgr_reset(); break; // ESC[0m - reset
|
|
|
|
case 0: current_style_->sgr_reset(); break; // ESC[0m - reset
|
|
|
|
case 1: current_style_.sgr_bold(1); break; // ESC[1m - bold
|
|
|
|
case 1: current_style_->sgr_bold(1); break; // ESC[1m - bold
|
|
|
|
case 2: current_style_.sgr_dim(1); break; // ESC[2m - dim
|
|
|
|
case 2: current_style_->sgr_dim(1); break; // ESC[2m - dim
|
|
|
|
case 3: current_style_.sgr_italic(1); break; // ESC[3m - italic
|
|
|
|
case 3: current_style_->sgr_italic(1); break; // ESC[3m - italic
|
|
|
|
case 4: current_style_.sgr_underline(1);break; // ESC[4m - underline
|
|
|
|
case 4: current_style_->sgr_underline(1);break; // ESC[4m - underline
|
|
|
|
case 5: current_style_.sgr_blink(1); break; // ESC[5m - blink
|
|
|
|
case 5: current_style_->sgr_blink(1); break; // ESC[5m - blink
|
|
|
|
case 6: handle_unknown_char(); break; // ESC[6m - (unused)
|
|
|
|
case 6: handle_unknown_char(); break; // ESC[6m - (unused)
|
|
|
|
case 7: current_style_.sgr_inverse(1); break; // ESC[7m - inverse
|
|
|
|
case 7: current_style_->sgr_inverse(1); break; // ESC[7m - inverse
|
|
|
|
case 8: handle_unknown_char(); break; // ESC[8m - (unused)
|
|
|
|
case 8: handle_unknown_char(); break; // ESC[8m - (unused)
|
|
|
|
case 9: current_style_.sgr_strike(1); break; // ESC[9m - strikeout
|
|
|
|
case 9: current_style_->sgr_strike(1); break; // ESC[9m - strikeout
|
|
|
|
} |
|
|
|
} |
|
|
|
} else if (val >= 21 && val <= 29) { // attribute extras
|
|
|
|
} else if (val >= 21 && val <= 29) { // attribute extras
|
|
|
|
switch ( val ) { |
|
|
|
switch ( val ) { |
|
|
|
case 21: current_style_.sgr_dbl_under(1);break; // ESC[21m - doubly underline
|
|
|
|
case 21: current_style_->sgr_dbl_under(1);break; // ESC[21m - doubly underline
|
|
|
|
case 22: current_style_.sgr_dim(0); // ESC[22m - disable bold/dim
|
|
|
|
case 22: current_style_->sgr_dim(0); // ESC[22m - disable bold/dim
|
|
|
|
current_style_.sgr_bold(0); break; //
|
|
|
|
current_style_->sgr_bold(0); break; //
|
|
|
|
case 23: current_style_.sgr_italic(0); break; // ESC[23m - disable italic
|
|
|
|
case 23: current_style_->sgr_italic(0); break; // ESC[23m - disable italic
|
|
|
|
case 24: current_style_.sgr_underline(0);break; // ESC[24m - disable underline
|
|
|
|
case 24: current_style_->sgr_underline(0);break; // ESC[24m - disable underline
|
|
|
|
case 25: current_style_.sgr_blink(0); break; // ESC[25m - disable blink
|
|
|
|
case 25: current_style_->sgr_blink(0); break; // ESC[25m - disable blink
|
|
|
|
case 26: handle_unknown_char(); break; // ESC[26m - (unused)
|
|
|
|
case 26: handle_unknown_char(); break; // ESC[26m - (unused)
|
|
|
|
case 27: current_style_.sgr_inverse(0); break; // ESC[27m - disable inverse
|
|
|
|
case 27: current_style_->sgr_inverse(0); break; // ESC[27m - disable inverse
|
|
|
|
case 28: handle_unknown_char(); break; // ESC[28m - disable hidden
|
|
|
|
case 28: handle_unknown_char(); break; // ESC[28m - disable hidden
|
|
|
|
case 29: current_style_.sgr_strike(0); break; // ESC[29m - disable strikeout
|
|
|
|
case 29: current_style_->sgr_strike(0); break; // ESC[29m - disable strikeout
|
|
|
|
} |
|
|
|
} |
|
|
|
} else if (val >= 30 && val <= 37) { // Set fg color?
|
|
|
|
} else if (val >= 30 && val <= 37) { // Set fg color?
|
|
|
|
current_style_.fgcolor_uchar(val - 30); |
|
|
|
current_style_->fgcolor_uchar(val - 30); |
|
|
|
} else if (val == 39) { // ESC[39m -- "normal" fg color:
|
|
|
|
} else if (val == 39) { // ESC[39m -- "normal" fg color:
|
|
|
|
Fl_Color fg = current_style_.defaultfgcolor(); // ..get default color
|
|
|
|
Fl_Color fg = current_style_->defaultfgcolor(); // ..get default color
|
|
|
|
current_style_.fgcolor(fg); // ..set current color
|
|
|
|
current_style_->fgcolor(fg); // ..set current color
|
|
|
|
} else if (val >= 40 && val <= 47) { // Set bg color?
|
|
|
|
} else if (val >= 40 && val <= 47) { // Set bg color?
|
|
|
|
current_style_.bgcolor_uchar(val - 40); |
|
|
|
current_style_->bgcolor_uchar(val - 40); |
|
|
|
} else if (val == 49) { // ESC[49m -- "normal" bg color:
|
|
|
|
} else if (val == 49) { // ESC[49m -- "normal" bg color:
|
|
|
|
Fl_Color bg = current_style_.defaultbgcolor(); // ..get default bg color
|
|
|
|
Fl_Color bg = current_style_->defaultbgcolor(); // ..get default bg color
|
|
|
|
current_style_.bgcolor(bg); // ..set current bg color
|
|
|
|
current_style_->bgcolor(bg); // ..set current bg color
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
handle_unknown_char(); // does an escseq.reset() // unimplemented SGR codes
|
|
|
|
handle_unknown_char(); // does an escseq.reset() // unimplemented SGR codes
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -2624,7 +2707,7 @@ void Fl_Terminal::display_modified(void) { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void Fl_Terminal::clear_char_at_disp(int drow, int dcol) { |
|
|
|
void Fl_Terminal::clear_char_at_disp(int drow, int dcol) { |
|
|
|
Utf8Char *u8c = u8c_disp_row(drow) + dcol; |
|
|
|
Utf8Char *u8c = u8c_disp_row(drow) + dcol; |
|
|
|
u8c->clear(current_style_); |
|
|
|
u8c->clear(*current_style_); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -2676,7 +2759,7 @@ void Fl_Terminal::putchar(const char *text, int len, int drow, int dcol) { |
|
|
|
// text_utf8() warns we must do invalid checks first
|
|
|
|
// text_utf8() warns we must do invalid checks first
|
|
|
|
if (!text || len<1 || len>u8c->max_utf8() || len!=fl_utf8len(*text)) |
|
|
|
if (!text || len<1 || len>u8c->max_utf8() || len!=fl_utf8len(*text)) |
|
|
|
{ handle_unknown_char(); return; } |
|
|
|
{ handle_unknown_char(); return; } |
|
|
|
u8c->text_utf8(text, len, current_style_); |
|
|
|
u8c->text_utf8(text, len, *current_style_); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -2700,7 +2783,7 @@ void Fl_Terminal::putchar(const char *text, int len, int drow, int dcol) { |
|
|
|
void Fl_Terminal::putchar(char c, int drow, int dcol) { |
|
|
|
void Fl_Terminal::putchar(char c, int drow, int dcol) { |
|
|
|
if (!is_printable(c)) { handle_unknown_char(); return; } |
|
|
|
if (!is_printable(c)) { handle_unknown_char(); return; } |
|
|
|
Utf8Char *u8c = u8c_disp_row(drow) + dcol; |
|
|
|
Utf8Char *u8c = u8c_disp_row(drow) + dcol; |
|
|
|
u8c->text_ascii(c, current_style_); |
|
|
|
u8c->text_ascii(c, *current_style_); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -3003,16 +3086,47 @@ void Fl_Terminal::redraw_timer_cb(void *udata) { |
|
|
|
\param[in] L label string (optional), may be NULL. |
|
|
|
\param[in] L label string (optional), may be NULL. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
Fl_Terminal::Fl_Terminal(int X,int Y,int W,int H,const char*L) : Fl_Group(X,Y,W,H,L) { |
|
|
|
Fl_Terminal::Fl_Terminal(int X,int Y,int W,int H,const char*L) : Fl_Group(X,Y,W,H,L) { |
|
|
|
|
|
|
|
bool fontsize_defer = false; |
|
|
|
|
|
|
|
init_(X,Y,W,H,L,-1,-1,100,fontsize_defer); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
Same as the default FLTK constructor, but lets the user force the rows, columns |
|
|
|
|
|
|
|
and history to specific sizes on creation. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Since the row/cols/hist are specified directly, this prevents the widget from auto-calculating |
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
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) : Fl_Group(X,Y,W,H,L) { |
|
|
|
|
|
|
|
bool fontsize_defer = true; |
|
|
|
|
|
|
|
init_(X,Y,W,H,L,rows,cols,hist,fontsize_defer); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Private contructor method
|
|
|
|
|
|
|
|
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); |
|
|
|
// 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(); |
|
|
|
// Tabs
|
|
|
|
// Tabs
|
|
|
|
tabstops_ = 0; |
|
|
|
tabstops_ = 0; |
|
|
|
tabstops_size_ = 0; |
|
|
|
tabstops_size_ = 0; |
|
|
|
// Init ringbuffer. Also creates default tabstops
|
|
|
|
// Init ringbuffer. Also creates default tabstops
|
|
|
|
create_ring(h_to_row(scrn_.h()), // desired row
|
|
|
|
if ( rows == -1 || cols == -1 ) { |
|
|
|
w_to_col(scrn_.w()), // desired col
|
|
|
|
int newrows = h_to_row(scrn_.h()); // rows based on height
|
|
|
|
100); // history size: use 100 for production release
|
|
|
|
int newcols = w_to_col(scrn_.w()); // cols based on width
|
|
|
|
|
|
|
|
// Sanity check
|
|
|
|
|
|
|
|
newrows = (newrows >= 1) ? newrows : 1; |
|
|
|
|
|
|
|
newcols = (newcols >= 1) ? newcols : 1; |
|
|
|
|
|
|
|
create_ring(newrows, newcols, hist); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
create_ring(rows, cols, 100); |
|
|
|
|
|
|
|
} |
|
|
|
// Misc
|
|
|
|
// Misc
|
|
|
|
redraw_style_ = RATE_LIMITED; // NO_REDRAW, RATE_LIMITED, PER_WRITE
|
|
|
|
redraw_style_ = RATE_LIMITED; // NO_REDRAW, RATE_LIMITED, PER_WRITE
|
|
|
|
redraw_rate_ = 0.10f; // maximum rate in seconds (1/10=10fps)
|
|
|
|
redraw_rate_ = 0.10f; // maximum rate in seconds (1/10=10fps)
|
|
|
@ -3108,8 +3222,8 @@ void Fl_Terminal::scrollbar_size(int val) { |
|
|
|
no pixels are drawn. |
|
|
|
no pixels are drawn. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void Fl_Terminal::draw_row_bg(int grow, int X, int Y) const { |
|
|
|
void Fl_Terminal::draw_row_bg(int grow, int X, int Y) const { |
|
|
|
int bg_h = current_style_.fontheight(); |
|
|
|
int bg_h = current_style_->fontheight(); |
|
|
|
int bg_y = Y - current_style_.fontheight() + current_style_.fontdescent(); |
|
|
|
int bg_y = Y - current_style_->fontheight() + current_style_->fontdescent(); |
|
|
|
Fl_Color bg_col; |
|
|
|
Fl_Color bg_col; |
|
|
|
int pwidth = 9; |
|
|
|
int pwidth = 9; |
|
|
|
const Utf8Char *u8c = u8c_ring_row(grow); // start of spec'd row
|
|
|
|
const Utf8Char *u8c = u8c_ring_row(grow); // start of spec'd row
|
|
|
@ -3117,7 +3231,7 @@ void Fl_Terminal::draw_row_bg(int grow, int X, int Y) const { |
|
|
|
for (int gcol=0; gcol<ring_cols(); gcol++,u8c++) { // walk columns
|
|
|
|
for (int gcol=0; gcol<ring_cols(); gcol++,u8c++) { // walk columns
|
|
|
|
// Attribute changed since last char?
|
|
|
|
// Attribute changed since last char?
|
|
|
|
if (gcol==0 || u8c->attrib() != lastattr) { |
|
|
|
if (gcol==0 || u8c->attrib() != lastattr) { |
|
|
|
u8c->fl_font_set(current_style_); // pwidth_int() needs fl_font set
|
|
|
|
u8c->fl_font_set(*current_style_); // pwidth_int() needs fl_font set
|
|
|
|
lastattr = u8c->attrib(); |
|
|
|
lastattr = u8c->attrib(); |
|
|
|
} |
|
|
|
} |
|
|
|
pwidth = u8c->pwidth_int(); |
|
|
|
pwidth = u8c->pwidth_int(); |
|
|
@ -3149,7 +3263,7 @@ void Fl_Terminal::draw_row(int grow, int Y) const { |
|
|
|
int disp_top = (disp_srow() - scrollval); // top row we need to view
|
|
|
|
int disp_top = (disp_srow() - scrollval); // top row we need to view
|
|
|
|
int drow = grow - disp_top; // disp row
|
|
|
|
int drow = grow - disp_top; // disp row
|
|
|
|
bool inside_display = is_disp_ring_row(grow); // row inside 'display'?
|
|
|
|
bool inside_display = is_disp_ring_row(grow); // row inside 'display'?
|
|
|
|
int strikeout_y = Y - (current_style_.fontheight() / 3); |
|
|
|
int strikeout_y = Y - (current_style_->fontheight() / 3); |
|
|
|
int underline_y = Y; |
|
|
|
int underline_y = Y; |
|
|
|
const Utf8Char *u8c = u8c_ring_row(grow); |
|
|
|
const Utf8Char *u8c = u8c_ring_row(grow); |
|
|
|
uchar lastattr = -1; |
|
|
|
uchar lastattr = -1; |
|
|
@ -3161,14 +3275,14 @@ void Fl_Terminal::draw_row(int grow, int Y) const { |
|
|
|
is_cursor = inside_display ? cursor_.is_rowcol(drow-scrollval, dcol) : 0; |
|
|
|
is_cursor = inside_display ? cursor_.is_rowcol(drow-scrollval, dcol) : 0; |
|
|
|
// Attribute changed since last char?
|
|
|
|
// Attribute changed since last char?
|
|
|
|
if (u8c->attrib() != lastattr) { |
|
|
|
if (u8c->attrib() != lastattr) { |
|
|
|
u8c->fl_font_set(current_style_); // pwidth_int() needs fl_font set
|
|
|
|
u8c->fl_font_set(*current_style_); // pwidth_int() needs fl_font set
|
|
|
|
lastattr = u8c->attrib(); |
|
|
|
lastattr = u8c->attrib(); |
|
|
|
} |
|
|
|
} |
|
|
|
int pwidth = u8c->pwidth_int(); |
|
|
|
int pwidth = u8c->pwidth_int(); |
|
|
|
// DRAW CURSOR BLOCK - TODO: support other cursor types?
|
|
|
|
// DRAW CURSOR BLOCK - TODO: support other cursor types?
|
|
|
|
if (is_cursor) { |
|
|
|
if (is_cursor) { |
|
|
|
int cx = X; |
|
|
|
int cx = X; |
|
|
|
int cy = Y - cursor_.h() + current_style_.fontdescent(); |
|
|
|
int cy = Y - cursor_.h() + current_style_->fontdescent(); |
|
|
|
int cw = pwidth; |
|
|
|
int cw = pwidth; |
|
|
|
int ch = cursor_.h(); |
|
|
|
int ch = cursor_.h(); |
|
|
|
fl_color(cursorbgcolor()); |
|
|
|
fl_color(cursorbgcolor()); |
|
|
@ -3211,7 +3325,7 @@ void Fl_Terminal::draw_row(int grow, int Y) const { |
|
|
|
void Fl_Terminal::draw_buff(int Y) const { |
|
|
|
void Fl_Terminal::draw_buff(int Y) const { |
|
|
|
int srow = disp_srow() - vscroll_->value(); |
|
|
|
int srow = disp_srow() - vscroll_->value(); |
|
|
|
int erow = srow + disp_rows(); |
|
|
|
int erow = srow + disp_rows(); |
|
|
|
const int rowheight = current_style_.fontheight(); |
|
|
|
const int rowheight = current_style_->fontheight(); |
|
|
|
for (int grow=srow; (grow<erow) && (Y<scrn_.b()); grow++) { |
|
|
|
for (int grow=srow; (grow<erow) && (Y<scrn_.b()); grow++) { |
|
|
|
Y += rowheight; // advance Y to bottom left corner of row
|
|
|
|
Y += rowheight; // advance Y to bottom left corner of row
|
|
|
|
draw_row(grow, Y); // draw global row at Y
|
|
|
|
draw_row(grow, Y); // draw global row at Y
|
|
|
@ -3224,6 +3338,12 @@ void Fl_Terminal::draw_buff(int Y) const { |
|
|
|
followed by the terminal's screen contents. |
|
|
|
followed by the terminal's screen contents. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void Fl_Terminal::draw(void) { |
|
|
|
void Fl_Terminal::draw(void) { |
|
|
|
|
|
|
|
// First time shown? Force deferred font size calculations here (issue 837)
|
|
|
|
|
|
|
|
if (fontsize_defer_) { |
|
|
|
|
|
|
|
fontsize_defer_ = false; // clear flag
|
|
|
|
|
|
|
|
current_style_->update(); // do deferred update here
|
|
|
|
|
|
|
|
update_screen(true); // update fonts
|
|
|
|
|
|
|
|
} |
|
|
|
// Draw group first, terminal last
|
|
|
|
// Draw group first, terminal last
|
|
|
|
Fl_Group::draw(); |
|
|
|
Fl_Group::draw(); |
|
|
|
|
|
|
|
|
|
|
@ -3255,7 +3375,7 @@ void Fl_Terminal::draw(void) { |
|
|
|
This is used by the constructor to size the row/cols to fit the widget size. |
|
|
|
This is used by the constructor to size the row/cols to fit the widget size. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
int Fl_Terminal::w_to_col(int W) const { |
|
|
|
int Fl_Terminal::w_to_col(int W) const { |
|
|
|
return int((float(W) / current_style_.charwidth()) + 0.0); // +.5 overshoots
|
|
|
|
return int((float(W) / current_style_->charwidth()) + 0.0); // +.5 overshoots
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -3263,7 +3383,7 @@ int Fl_Terminal::w_to_col(int W) const { |
|
|
|
This is used by the constructor to size the row/cols to fit the widget size. |
|
|
|
This is used by the constructor to size the row/cols to fit the widget size. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
int Fl_Terminal::h_to_row(int H) const { |
|
|
|
int Fl_Terminal::h_to_row(int H) const { |
|
|
|
return int((float(H) / current_style_.fontheight()) + -0.5); // +.5 overshoots
|
|
|
|
return int((float(H) / current_style_->fontheight()) + -0.5); // +.5 overshoots
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|