Merge pull request #80 from gansm/master

merge
This commit is contained in:
Markus Gans 2020-11-14 22:58:38 +01:00 committed by GitHub
commit c52b22b4a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 4021 additions and 4068 deletions

View File

@ -1,5 +1,11 @@
2019-11-14 Markus Gans <guru.mail@muenster.de>
* Version 0.7.1
* Bugfix: The cursor position was not changed anymore
if there was no change to the content
* Forcing a direct update for faster terminal output
2019-11-07 Markus Gans <guru.mail@muenster.de> 2019-11-07 Markus Gans <guru.mail@muenster.de>
* Version 0.7.0 * Version 0.7.0
2020-11-04 Markus Gans <guru.mail@muenster.de> 2020-11-04 Markus Gans <guru.mail@muenster.de>
* Elimination of unnecessary terminal flushes * Elimination of unnecessary terminal flushes

View File

@ -2,7 +2,7 @@
# Library for creating terminal applications with text-based widgets # Library for creating terminal applications with text-based widgets
The FINAL CUT is a C++ class library and widget toolkit with full [mouse](doc/mouse-control.md#title-bar-actions-on-mouse-clicks) support for creating a [text-based user interface](https://en.wikipedia.org/wiki/Text-based_user_interface). The library supports the programmer to develop an application for the text console. It allows the simultaneous handling of multiple text windows on the screen. FINAL CUT is a C++ class library and widget toolkit with full [mouse](doc/mouse-control.md#title-bar-actions-on-mouse-clicks) support for creating a [text-based user interface](https://en.wikipedia.org/wiki/Text-based_user_interface). The library supports the programmer to develop an application for the text console. It allows the simultaneous handling of multiple text windows on the screen.
The structure of the Qt framework was originally the inspiration for the C++ class design of FINAL CUT. It provides common controls like dialog boxes, push buttons, check boxes, radio buttons, input lines, list boxes, status bars and so on. The structure of the Qt framework was originally the inspiration for the C++ class design of FINAL CUT. It provides common controls like dialog boxes, push buttons, check boxes, radio buttons, input lines, list boxes, status bars and so on.

View File

@ -4,7 +4,7 @@
# Process this file with autoconf to produce a configure script. # Process this file with autoconf to produce a configure script.
AC_INIT([finalcut], [0.7.0]) AC_INIT([finalcut], [0.7.1])
AC_CONFIG_HEADER([config.h]) AC_CONFIG_HEADER([config.h])
AX_PREFIX_CONFIG_H([src/include/final/fconfig.h], [F]) AX_PREFIX_CONFIG_H([src/include/final/fconfig.h], [F])
AC_CONFIG_SRCDIR([src/fobject.cpp]) AC_CONFIG_SRCDIR([src/fobject.cpp])
@ -64,7 +64,7 @@ LT_OUTPUT
### This defines the version number of the installed .so files ### This defines the version number of the installed .so files
### Update this value for every release! (A:B:C will map to foo.so.(A-C).C.B) ### Update this value for every release! (A:B:C will map to foo.so.(A-C).C.B)
### using libtool's versioning system. ### using libtool's versioning system.
AC_SUBST(SO_VERSION, ["7:0:7"]) AC_SUBST(SO_VERSION, ["7:1:7"])
AC_SUBST([LIBTOOL_DEPS]) AC_SUBST([LIBTOOL_DEPS])

6
debian/changelog vendored
View File

@ -1,3 +1,9 @@
finalcut (0.7.1) unstable; urgency=low
* Release (version 0.7.1)
-- Markus Gans <guru.mail@muenster.de> Sat, 14 Nov 2020 20:07:39 +0100
finalcut (0.7.0) unstable; urgency=low finalcut (0.7.0) unstable; urgency=low
* Release (version 0.7.0) * Release (version 0.7.0)

View File

@ -1 +1 @@
libfinal 0 libfinal0 (>= 0.7.0) libfinal 0 libfinal0 (>= 0.7.1)

7578
debian/libfinal0.symbols vendored

File diff suppressed because it is too large Load Diff

View File

@ -225,7 +225,7 @@ void RotoZoomer::onShow (finalcut::FShowEvent*)
for (path = 1; path < loops; path++) for (path = 1; path < loops; path++)
{ {
redraw(); redraw();
processTerminalUpdate(); forceTerminalUpdate();
} }
end = system_clock::now(); end = system_clock::now();
@ -244,6 +244,7 @@ void RotoZoomer::onTimer (finalcut::FTimerEvent*)
path++; path++;
redraw(); redraw();
forceTerminalUpdate();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -1,3 +1,7 @@
-------------------------------------------------------------------
Sat Nov 14 20:13:57 UTC 2020 - Markus Gans <guru.mail@muenster.de>
- Release (version 0.7.1)
------------------------------------------------------------------- -------------------------------------------------------------------
Sat Nov 07 11:24:39 UTC 2020 - Markus Gans <guru.mail@muenster.de> Sat Nov 07 11:24:39 UTC 2020 - Markus Gans <guru.mail@muenster.de>
- Release (version 0.7.0) - Release (version 0.7.0)

View File

@ -1,6 +1,6 @@
sonar.projectKey=gansm_finalcut sonar.projectKey=gansm_finalcut
sonar.projectName=finalcut sonar.projectName=finalcut
sonar.projectVersion=0.7.0 sonar.projectVersion=0.7.1
sonar.projectDescription=A text-based widget toolkit sonar.projectDescription=A text-based widget toolkit
#---------------------------------------------------------------------- #----------------------------------------------------------------------

View File

@ -3,7 +3,7 @@
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# This is where make install will install the library # This is where make install will install the library
VERSION = "0.7.0" VERSION = "0.7.1"
MAJOR := $(shell echo ${VERSION} | cut -d. -f1) MAJOR := $(shell echo ${VERSION} | cut -d. -f1)
LIBDIR = /usr/local/lib LIBDIR = /usr/local/lib
INCLUDEDIR1 = include/final INCLUDEDIR1 = include/final

View File

@ -3,7 +3,7 @@
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# This is where make install will install the library # This is where make install will install the library
VERSION = "0.7.0" VERSION = "0.7.1"
MAJOR := $(shell echo ${VERSION} | cut -d. -f1) MAJOR := $(shell echo ${VERSION} | cut -d. -f1)
LIBDIR = /usr/local/lib LIBDIR = /usr/local/lib
INCLUDEDIR1 = include/final INCLUDEDIR1 = include/final

View File

@ -357,9 +357,7 @@ void FLineEdit::onKeyPress (FKeyEvent* ev)
&& key != fc::Fkey_enter ) && key != fc::Fkey_enter )
{ {
drawInputField(); drawInputField();
forceTerminalUpdate();
if ( processTerminalUpdate() )
flush();
} }
} }
@ -399,9 +397,7 @@ void FLineEdit::onMouseDown (FMouseEvent* ev)
adjustTextOffset(); adjustTextOffset();
drawInputField(); drawInputField();
forceTerminalUpdate();
if ( processTerminalUpdate() )
flush();
} }
} }
@ -435,9 +431,7 @@ void FLineEdit::onMouseMove (FMouseEvent* ev)
adjustTextOffset(); adjustTextOffset();
drawInputField(); drawInputField();
forceTerminalUpdate();
if ( processTerminalUpdate() )
flush();
} }
// auto-scrolling when dragging mouse outside the widget // auto-scrolling when dragging mouse outside the widget
@ -540,9 +534,7 @@ void FLineEdit::onTimer (FTimerEvent*)
adjustTextOffset(); adjustTextOffset();
drawInputField(); drawInputField();
forceTerminalUpdate();
if ( processTerminalUpdate() )
flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -352,8 +352,7 @@ void FListBox::onMouseDown (FMouseEvent* ev)
if ( yoffset_before != yoffset ) if ( yoffset_before != yoffset )
vbar->drawBar(); vbar->drawBar();
if ( processTerminalUpdate() ) forceTerminalUpdate();
flush();
} }
} }
@ -426,8 +425,7 @@ void FListBox::onMouseMove (FMouseEvent* ev)
if ( yoffset_before != yoffset ) if ( yoffset_before != yoffset )
vbar->drawBar(); vbar->drawBar();
if ( processTerminalUpdate() ) forceTerminalUpdate();
flush();
} }
// Auto-scrolling when dragging mouse outside the widget // Auto-scrolling when dragging mouse outside the widget
@ -504,8 +502,7 @@ void FListBox::onTimer (FTimerEvent*)
if ( yoffset_before != yoffset ) if ( yoffset_before != yoffset )
vbar->drawBar(); vbar->drawBar();
if ( processTerminalUpdate() ) forceTerminalUpdate();
flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -547,8 +544,7 @@ void FListBox::onWheel (FWheelEvent* ev)
if ( yoffset_before != yoffset ) if ( yoffset_before != yoffset )
vbar->drawBar(); vbar->drawBar();
if ( processTerminalUpdate() ) forceTerminalUpdate();
flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1082,8 +1078,7 @@ inline void FListBox::updateDrawing (bool draw_vbar, bool draw_hbar)
if ( draw_hbar ) if ( draw_hbar )
hbar->drawBar(); hbar->drawBar();
if ( processTerminalUpdate() ) forceTerminalUpdate();
flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1803,8 +1798,7 @@ void FListBox::cb_vbarChange (const FWidget*)
if ( yoffset_before != yoffset ) if ( yoffset_before != yoffset )
vbar->drawBar(); vbar->drawBar();
if ( processTerminalUpdate() ) forceTerminalUpdate();
flush();
} }
} }
@ -1872,8 +1866,7 @@ void FListBox::cb_hbarChange (const FWidget*)
if ( xoffset_before != xoffset ) if ( xoffset_before != xoffset )
hbar->drawBar(); hbar->drawBar();
if ( processTerminalUpdate() ) forceTerminalUpdate();
flush();
} }
} }

View File

@ -1116,8 +1116,7 @@ void FListView::onMouseDown (FMouseEvent* ev)
if ( first_line_position_before != first_visible_line.getPosition() ) if ( first_line_position_before != first_visible_line.getPosition() )
vbar->drawBar(); vbar->drawBar();
if ( processTerminalUpdate() ) forceTerminalUpdate();
flush();
} }
} }
} }
@ -1221,8 +1220,7 @@ void FListView::onMouseMove (FMouseEvent* ev)
if ( first_line_position_before != first_visible_line.getPosition() ) if ( first_line_position_before != first_visible_line.getPosition() )
vbar->drawBar(); vbar->drawBar();
if ( processTerminalUpdate() ) forceTerminalUpdate();
flush();
} }
// auto-scrolling when dragging mouse outside the widget // auto-scrolling when dragging mouse outside the widget
@ -1308,8 +1306,7 @@ void FListView::onTimer (FTimerEvent*)
if ( first_line_position_before != first_visible_line.getPosition() ) if ( first_line_position_before != first_visible_line.getPosition() )
vbar->drawBar(); vbar->drawBar();
if ( processTerminalUpdate() ) forceTerminalUpdate();
flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1347,8 +1344,7 @@ void FListView::onWheel (FWheelEvent* ev)
if ( first_line_position_before != first_visible_line.getPosition() ) if ( first_line_position_before != first_visible_line.getPosition() )
vbar->drawBar(); vbar->drawBar();
if ( processTerminalUpdate() ) forceTerminalUpdate();
flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -2152,8 +2148,7 @@ void FListView::updateDrawing (bool draw_vbar, bool draw_hbar)
if ( draw_hbar ) if ( draw_hbar )
hbar->drawBar(); hbar->drawBar();
if ( processTerminalUpdate() ) forceTerminalUpdate();
flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -2872,8 +2867,7 @@ void FListView::cb_vbarChange (const FWidget*)
if ( first_line_position_before != first_visible_line.getPosition() ) if ( first_line_position_before != first_visible_line.getPosition() )
vbar->drawBar(); vbar->drawBar();
if ( processTerminalUpdate() ) forceTerminalUpdate();
flush();
} }
} }
@ -2938,8 +2932,7 @@ void FListView::cb_hbarChange (const FWidget*)
if ( xoffset_before != xoffset ) if ( xoffset_before != xoffset )
hbar->drawBar(); hbar->drawBar();
if ( processTerminalUpdate() ) forceTerminalUpdate();
flush();
} }
} }

View File

@ -311,9 +311,7 @@ void FMenu::onMouseMove (FMouseEvent* ev)
else if ( ms.hide_sub_menu ) else if ( ms.hide_sub_menu )
{ {
closeOpenedSubMenu(); closeOpenedSubMenu();
forceTerminalUpdate();
if ( processTerminalUpdate() )
flush();
} }
} }
@ -1060,6 +1058,7 @@ bool FMenu::selectNextItem()
getStatusBar()->drawMessage(); getStatusBar()->drawMessage();
redraw(); redraw();
forceTerminalUpdate();
break; break;
} }
@ -1108,6 +1107,7 @@ bool FMenu::selectPrevItem()
getStatusBar()->drawMessage(); getStatusBar()->drawMessage();
redraw(); redraw();
forceTerminalUpdate();
break; break;
} }
} }

View File

@ -223,10 +223,7 @@ void FMenuBar::onAccel (FAccelEvent* ev)
getStatusBar()->drawMessage(); getStatusBar()->drawMessage();
redraw(); redraw();
forceTerminalUpdate();
if ( processTerminalUpdate() )
flush();
ev->accept(); ev->accept();
} }
@ -339,6 +336,7 @@ bool FMenuBar::selectNextItem()
redraw(); redraw();
setTerminalUpdates (FVTerm::start_terminal_updates); setTerminalUpdates (FVTerm::start_terminal_updates);
forceTerminalUpdate();
break; break;
} }
@ -403,6 +401,7 @@ bool FMenuBar::selectPrevItem()
setSelectedItem(prev); setSelectedItem(prev);
redraw(); redraw();
setTerminalUpdates (FVTerm::start_terminal_updates); setTerminalUpdates (FVTerm::start_terminal_updates);
forceTerminalUpdate();
break; break;
} }
} }
@ -922,9 +921,7 @@ void FMenuBar::mouseMoveOverList (const FMouseEvent&& ev)
if ( focus_changed ) if ( focus_changed )
{ {
redraw(); redraw();
forceTerminalUpdate();
if ( processTerminalUpdate() )
flush();
} }
} }

View File

@ -417,7 +417,6 @@ void FMenuItem::onAccel (FAccelEvent* ev)
mbar->redraw(); mbar->redraw();
mbar->drop_down = true; mbar->drop_down = true;
} }
else else
{ {
@ -428,9 +427,7 @@ void FMenuItem::onAccel (FAccelEvent* ev)
mbar->drop_down = false; mbar->drop_down = false;
} }
if ( processTerminalUpdate() ) forceTerminalUpdate();
flush();
ev->accept(); ev->accept();
} }

View File

@ -557,7 +557,7 @@ const char* FOptiAttr::changeAttribute (FChar& term, FChar& next)
// Simulate invisible characters // Simulate invisible characters
if ( ! F_enter_secure_mode.cap && next.attr.bit.invisible ) if ( ! F_enter_secure_mode.cap && next.attr.bit.invisible )
next.encoded_char = ' '; next.encoded_char[0] = ' ';
// Look for no changes // Look for no changes
if ( ! (switchOn() || switchOff() || hasColorChanged(term, next)) ) if ( ! (switchOn() || switchOff() || hasColorChanged(term, next)) )

View File

@ -144,8 +144,7 @@ void FProgressbar::draw()
if ( getFlags().shadow ) if ( getFlags().shadow )
drawShadow(this); drawShadow(this);
if ( processTerminalUpdate() ) forceTerminalUpdate();
flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -352,10 +352,7 @@ void FScrollbar::onMouseMove (FMouseEvent* ev)
{ {
setValue(new_val); setValue(new_val);
drawBar(); drawBar();
forceTerminalUpdate();
if ( processTerminalUpdate() )
flush();
processScroll(); processScroll();
} }
} }
@ -760,10 +757,7 @@ void FScrollbar::jumpToClickPos (int x, int y)
{ {
setValue(new_val); setValue(new_val);
drawBar(); drawBar();
forceTerminalUpdate();
if ( processTerminalUpdate() )
flush();
scroll_type = FScrollbar::scrollJump; scroll_type = FScrollbar::scrollJump;
processScroll(); processScroll();
} }

View File

@ -411,9 +411,7 @@ void FScrollView::scrollTo (int x, int y)
viewport->has_changes = true; viewport->has_changes = true;
copy2area(); copy2area();
forceTerminalUpdate();
if ( processTerminalUpdate() )
flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -342,12 +342,6 @@ const FString& FString::operator () () const
// public methods of FString // public methods of FString
//----------------------------------------------------------------------
std::size_t FString::getUTF8length() const
{
return length;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
FString FString::clear() FString FString::clear()
{ {

View File

@ -158,11 +158,11 @@ const wchar_t ambiguous_width_list[] =
0x25d0, 0x25d1, 0x25d8, 0x25d9, 0x25e2, 0x25e3, 0x25e4, 0x25e5, 0x25d0, 0x25d1, 0x25d8, 0x25d9, 0x25e2, 0x25e3, 0x25e4, 0x25e5,
0x25ef, 0x2605, 0x2606, 0x2609, 0x260e, 0x260f, 0x2614, 0x2615, 0x25ef, 0x2605, 0x2606, 0x2609, 0x260e, 0x260f, 0x2614, 0x2615,
0x261c, 0x261e, 0x2640, 0x2642, 0x2660, 0x2661, 0x2663, 0x2664, 0x261c, 0x261e, 0x2640, 0x2642, 0x2660, 0x2661, 0x2663, 0x2664,
0x2665, 0x2667, 0x2668, 0x2669, 0x266a, 0x266c, 0x266d, 0x266f, 0x2665, 0x2666, 0x2667, 0x2668, 0x2669, 0x266a, 0x266c, 0x266d,
0x273d, 0x2776, 0x2777, 0x2778, 0x2779, 0x277a, 0x277b, 0x277c, 0x266f, 0x273d, 0x2776, 0x2777, 0x2778, 0x2779, 0x277a, 0x277b,
0x277d, 0x277e, 0x277f, 0xfe00, 0xfe01, 0xfe02, 0xfe03, 0xfe04, 0x277c, 0x277d, 0x277e, 0x277f, 0xfe00, 0xfe01, 0xfe02, 0xfe03,
0xfe05, 0xfe07, 0xfe09, 0xfe0a, 0xfe0b, 0xfe0c, 0xfe0d, 0xfe0e, 0xfe04, 0xfe05, 0xfe07, 0xfe09, 0xfe0a, 0xfe0b, 0xfe0c, 0xfe0d,
0xfe0f, 0xfffd 0xfe0e, 0xfe0f, 0xfffd
#if !defined(__CYGWIN__) #if !defined(__CYGWIN__)
, 0xe0100, 0xe0101, 0xe0102, 0xe0103, 0xe0104, 0xe0105, 0xe0106, , 0xe0100, 0xe0101, 0xe0102, 0xe0103, 0xe0104, 0xe0105, 0xe0106,
0xe0107, 0xe0108, 0xe0109, 0xe010a, 0xe01ef 0xe0107, 0xe0108, 0xe0109, 0xe010a, 0xe01ef
@ -507,11 +507,11 @@ std::size_t getColumnWidth (const wchar_t wchar)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
std::size_t getColumnWidth (FChar& term_char) std::size_t getColumnWidth (FChar& term_char)
{ {
const std::size_t char_width = getColumnWidth(term_char.ch); const std::size_t char_width = getColumnWidth(term_char.ch[0]);
if ( char_width == 2 && FTerm::getEncoding() != fc::UTF8 ) if ( char_width == 2 && FTerm::getEncoding() != fc::UTF8 )
{ {
term_char.ch = '.'; term_char.ch[0] = '.';
term_char.attr.bit.char_width = 1; term_char.attr.bit.char_width = 1;
} }
else else
@ -526,7 +526,7 @@ std::size_t getColumnWidth (const FTermBuffer& tb)
return std::accumulate ( std::next(tb.begin()) return std::accumulate ( std::next(tb.begin())
, tb.end() , tb.end()
, tb.front().attr.bit.char_width , tb.front().attr.bit.char_width
, [] (std::size_t s, FChar c) , [] (std::size_t s, const FChar& c)
{ {
return std::move(s) + c.attr.bit.char_width; return std::move(s) + c.attr.bit.char_width;
} }

View File

@ -52,7 +52,7 @@ FString FTermBuffer::toString() const
, std::back_inserter(wide_string) , std::back_inserter(wide_string)
, [] (const FChar& fchar) , [] (const FChar& fchar)
{ {
return fchar.ch; return fchar.ch[0];
} }
); );
return wide_string; return wide_string;
@ -68,11 +68,11 @@ int FTermBuffer::write (const FString& string)
{ {
FChar nc; // next character FChar nc; // next character
nc = FVTerm::getAttribute(); nc = FVTerm::getAttribute();
nc.ch = c; nc.ch[0] = c;
nc.attr.byte[2] = 0;
nc.attr.byte[3] = 0;
getColumnWidth(nc); // add column width getColumnWidth(nc); // add column width
nc.attr.bit.no_changes = false; data.push_back(std::move(nc));
nc.attr.bit.printed = false;
data.push_back(nc);
} }
return len; return len;
@ -82,7 +82,7 @@ int FTermBuffer::write (const FString& string)
int FTermBuffer::write (wchar_t ch) int FTermBuffer::write (wchar_t ch)
{ {
FChar nc = FVTerm::getAttribute(); // next character FChar nc = FVTerm::getAttribute(); // next character
nc.ch = ch; nc.ch[0] = ch;
getColumnWidth(nc); // add column width getColumnWidth(nc); // add column width
nc.attr.bit.no_changes = false; nc.attr.bit.no_changes = false;
nc.attr.bit.printed = false; nc.attr.bit.printed = false;

View File

@ -184,9 +184,7 @@ void FTextView::scrollTo (int x, int y)
} }
drawText(); drawText();
forceTerminalUpdate();
if ( processTerminalUpdate() )
flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -477,8 +475,7 @@ void FTextView::onWheel (FWheelEvent* ev)
if ( isShown() ) if ( isShown() )
drawText(); drawText();
if ( processTerminalUpdate() ) forceTerminalUpdate();
flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -54,6 +54,7 @@ namespace finalcut
bool FVTerm::draw_completed{false}; bool FVTerm::draw_completed{false};
bool FVTerm::no_terminal_updates{false}; bool FVTerm::no_terminal_updates{false};
bool FVTerm::cursor_hideable{false}; bool FVTerm::cursor_hideable{false};
bool FVTerm::force_terminal_update{false};
int FVTerm::skipped_terminal_update{0}; int FVTerm::skipped_terminal_update{0};
uInt64 FVTerm::term_size_check_timeout{500000}; // 500 ms uInt64 FVTerm::term_size_check_timeout{500000}; // 500 ms
uInt FVTerm::erase_char_length{}; uInt FVTerm::erase_char_length{};
@ -286,9 +287,10 @@ bool FVTerm::updateTerminal() const
if ( updateTerminalLine(y) ) if ( updateTerminalLine(y) )
changedlines++; changedlines++;
if ( changedlines % check_interval == 0 if ( ! force_terminal_update
&& changedlines % check_interval == 0
&& (keyboard->hasUnprocessedInput() || keyboard->isKeyPressed(0) ) && (keyboard->hasUnprocessedInput() || keyboard->isKeyPressed(0) )
&& skipped_terminal_update <= max_skip ) && skipped_terminal_update < max_skip )
{ {
// Skipping terminal updates if there is unprocessed inputs // Skipping terminal updates if there is unprocessed inputs
skipped_terminal_update++; skipped_terminal_update++;
@ -300,8 +302,8 @@ bool FVTerm::updateTerminal() const
vterm->has_changes = false; vterm->has_changes = false;
// sets the new input cursor position // sets the new input cursor position
updateTerminalCursor(); bool cursor_update = updateTerminalCursor();
return changedlines > 0; return cursor_update || changedlines > 0;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -340,49 +342,45 @@ void FVTerm::delPreprocessingHandler (const FVTerm* instance)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
int FVTerm::print (const FString& s) int FVTerm::print (const FString& string)
{ {
if ( s.isNull() ) if ( string.isNull() )
return -1; return -1;
auto area = getPrintArea(); FTermBuffer term_buffer{};
term_buffer.write(string);
if ( ! area ) return print (term_buffer);
return -1;
return print (area, s);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
int FVTerm::print (FTermArea* area, const FString& s) int FVTerm::print (FTermArea* area, const FString& string)
{ {
if ( s.isNull() || ! area ) if ( ! area || string.isNull() )
return -1; return -1;
std::vector<FChar> term_string{}; FTermBuffer term_buffer{};
term_string.reserve(s.getLength()); term_buffer.write(string);
const wchar_t* p = s.wc_str(); return print (area, term_buffer);
}
if ( p ) //----------------------------------------------------------------------
{ int FVTerm::print (const std::vector<FChar>& term_string)
while ( *p ) {
{ if ( term_string.empty() )
FChar nc{}; // next character return -1;
nc.ch = *p;
nc.fg_color = next_attribute.fg_color;
nc.bg_color = next_attribute.bg_color;
nc.attr.byte[0] = next_attribute.attr.byte[0];
nc.attr.byte[1] = next_attribute.attr.byte[1];
nc.attr.byte[2] = 0;
nc.attr.byte[3] = 0;
term_string.push_back(std::move(nc));
p++;
} // end of while
return print (area, term_string); FTermBuffer term_buffer{term_string.begin(), term_string.end()};
} return print (term_buffer);
}
return 0; //----------------------------------------------------------------------
int FVTerm::print (FTermArea* area, const std::vector<FChar>& term_string)
{
if ( ! area || term_string.empty() )
return -1;
FTermBuffer term_buffer{term_string.begin(), term_string.end()};
return print (area, term_buffer);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -401,42 +399,18 @@ int FVTerm::print (const FTermBuffer& term_buffer)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
int FVTerm::print (FTermArea* area, const FTermBuffer& term_buffer) int FVTerm::print (FTermArea* area, const FTermBuffer& term_buffer)
{
const auto& term_string = term_buffer.getBuffer();
return print (area, term_string);
}
//----------------------------------------------------------------------
int FVTerm::print (const std::vector<FChar>& term_string)
{
if ( term_string.empty() )
return 0;
auto area = getPrintArea();
if ( ! area )
return -1;
return print (area, term_string);
}
//----------------------------------------------------------------------
int FVTerm::print (FTermArea* area, const std::vector<FChar>& term_string)
{ {
int len{0}; int len{0};
const auto tabstop = uInt(FTerm::getTabstop()); const auto tabstop = uInt(FTerm::getTabstop());
if ( ! area ) if ( ! area || term_buffer.isEmpty() )
return -1; return -1;
if ( term_string.empty() ) for (auto&& fchar : term_buffer)
return 0;
for (auto&& fchar : term_string)
{ {
bool printable_character{false}; bool printable_character{false};
switch ( fchar.ch ) switch ( fchar.ch[0] )
{ {
case '\n': case '\n':
area->cursor_y++; area->cursor_y++;
@ -478,30 +452,25 @@ int FVTerm::print (FTermArea* area, const std::vector<FChar>& term_string)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
int FVTerm::print (wchar_t c) int FVTerm::print (wchar_t c)
{ {
auto area = getPrintArea(); FChar nc{}; // next character
nc = FVTerm::getAttribute();
if ( ! area ) nc.ch[0] = c;
return -1; nc.attr.byte[2] = 0;
nc.attr.byte[3] = 0;
return print (area, c); return print (nc);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
int FVTerm::print (FTermArea* area, wchar_t c) int FVTerm::print (FTermArea* area, wchar_t c)
{ {
FChar nc{}; // next character
if ( ! area ) if ( ! area )
return -1; return -1;
nc.ch = wchar_t(c); FChar nc{}; // next character
nc.fg_color = next_attribute.fg_color; nc = FVTerm::getAttribute();
nc.bg_color = next_attribute.bg_color; nc.ch[0] = c;
nc.attr.byte[0] = next_attribute.attr.byte[0];
nc.attr.byte[1] = next_attribute.attr.byte[1];
nc.attr.byte[2] = 0; nc.attr.byte[2] = 0;
nc.attr.byte[3] = 0; nc.attr.byte[3] = 0;
return print (area, nc); return print (area, nc);
} }
@ -531,7 +500,10 @@ int FVTerm::print (FTermArea* area, FChar& term_char)
const int ax = area->cursor_x - 1; const int ax = area->cursor_x - 1;
const int ay = area->cursor_y - 1; const int ay = area->cursor_y - 1;
const std::size_t char_width = getColumnWidth(term_char); // add column width std::size_t char_width = term_char.attr.bit.char_width;
if ( char_width == 0 )
char_width = getColumnWidth(term_char); // add column width
if ( char_width == 0 && ! term_char.attr.bit.fullwidth_padding ) if ( char_width == 0 && ! term_char.attr.bit.fullwidth_padding )
return 0; return 0;
@ -1134,7 +1106,7 @@ void FVTerm::scrollAreaForward (FTermArea* area) const
auto bottom_right = std::size_t((y_max * total_width) - area->right_shadow - 1); auto bottom_right = std::size_t((y_max * total_width) - area->right_shadow - 1);
const auto& lc = area->data[bottom_right]; // last character const auto& lc = area->data[bottom_right]; // last character
std::memcpy (&nc, &lc, sizeof(nc)); std::memcpy (&nc, &lc, sizeof(nc));
nc.ch = ' '; nc.ch[0] = ' ';
auto& dc = area->data[y_max * total_width]; // destination character auto& dc = area->data[y_max * total_width]; // destination character
std::fill_n (&dc, area->width, nc); std::fill_n (&dc, area->width, nc);
area->changes[y_max].xmin = 0; area->changes[y_max].xmin = 0;
@ -1186,7 +1158,7 @@ void FVTerm::scrollAreaReverse (FTermArea* area) const
FChar nc{}; // next character FChar nc{}; // next character
const auto& lc = area->data[total_width]; // last character const auto& lc = area->data[total_width]; // last character
std::memcpy (&nc, &lc, sizeof(nc)); std::memcpy (&nc, &lc, sizeof(nc));
nc.ch = ' '; nc.ch[0] = ' ';
auto& dc = area->data[0]; // destination character auto& dc = area->data[0]; // destination character
std::fill_n (&dc, area->width, nc); std::fill_n (&dc, area->width, nc);
area->changes[0].xmin = 0; area->changes[0].xmin = 0;
@ -1217,7 +1189,7 @@ void FVTerm::clearArea (FTermArea* area, int fillchar) const
// Current attributes with a space character // Current attributes with a space character
std::memcpy (&nc, &next_attribute, sizeof(nc)); std::memcpy (&nc, &next_attribute, sizeof(nc));
nc.ch = fillchar; nc.ch[0] = fillchar;
if ( ! (area && area->data) ) if ( ! (area && area->data) )
{ {
@ -1261,6 +1233,15 @@ void FVTerm::clearArea (FTermArea* area, int fillchar) const
area->has_changes = true; area->has_changes = true;
} }
//----------------------------------------------------------------------
void FVTerm::forceTerminalUpdate() const
{
force_terminal_update = true;
processTerminalUpdate();
flush();
force_terminal_update = false;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool FVTerm::processTerminalUpdate() const bool FVTerm::processTerminalUpdate() const
{ {
@ -1278,7 +1259,8 @@ bool FVTerm::processTerminalUpdate() const
} }
// Update data on VTerm // Update data on VTerm
updateVTerm(); if ( force_terminal_update || skipped_terminal_update == 0 )
updateVTerm();
// Update the visible terminal // Update the visible terminal
return updateTerminal(); return updateTerminal();
@ -1324,7 +1306,7 @@ inline void FVTerm::resetTextAreaToDefault ( const FTermArea* area
FChar default_char; FChar default_char;
FLineChanges unchanged; FLineChanges unchanged;
default_char.ch = ' '; default_char.ch[0] = ' ';
default_char.fg_color = fc::Default; default_char.fg_color = fc::Default;
default_char.bg_color = fc::Default; default_char.bg_color = fc::Default;
default_char.attr.byte[0] = 0; default_char.attr.byte[0] = 0;
@ -1459,13 +1441,13 @@ inline void FVTerm::updateOverlappedColor ( const FChar& area_char
nc.attr.bit.reverse = false; nc.attr.bit.reverse = false;
nc.attr.bit.standout = false; nc.attr.bit.standout = false;
if ( nc.ch == fc::LowerHalfBlock if ( nc.ch[0] == fc::LowerHalfBlock
|| nc.ch == fc::UpperHalfBlock || nc.ch[0] == fc::UpperHalfBlock
|| nc.ch == fc::LeftHalfBlock || nc.ch[0] == fc::LeftHalfBlock
|| nc.ch == fc::RightHalfBlock || nc.ch[0] == fc::RightHalfBlock
|| nc.ch == fc::MediumShade || nc.ch[0] == fc::MediumShade
|| nc.ch == fc::FullBlock ) || nc.ch[0] == fc::FullBlock )
nc.ch = ' '; nc.ch[0] = ' ';
nc.attr.bit.no_changes = bool(vterm_char.attr.bit.printed && vterm_char == nc); nc.attr.bit.no_changes = bool(vterm_char.attr.bit.printed && vterm_char == nc);
std::memcpy (&vterm_char, &nc, sizeof(vterm_char)); std::memcpy (&vterm_char, &nc, sizeof(vterm_char));
@ -1494,13 +1476,13 @@ inline void FVTerm::updateShadedCharacter ( const FChar& area_char
cover_char.attr.bit.reverse = false; cover_char.attr.bit.reverse = false;
cover_char.attr.bit.standout = false; cover_char.attr.bit.standout = false;
if ( cover_char.ch == fc::LowerHalfBlock if ( cover_char.ch[0] == fc::LowerHalfBlock
|| cover_char.ch == fc::UpperHalfBlock || cover_char.ch[0] == fc::UpperHalfBlock
|| cover_char.ch == fc::LeftHalfBlock || cover_char.ch[0] == fc::LeftHalfBlock
|| cover_char.ch == fc::RightHalfBlock || cover_char.ch[0] == fc::RightHalfBlock
|| cover_char.ch == fc::MediumShade || cover_char.ch[0] == fc::MediumShade
|| cover_char.ch == fc::FullBlock ) || cover_char.ch[0] == fc::FullBlock )
cover_char.ch = ' '; cover_char.ch[0] = ' ';
cover_char.attr.bit.no_changes = \ cover_char.attr.bit.no_changes = \
bool(vterm_char.attr.bit.printed && vterm_char == cover_char); bool(vterm_char.attr.bit.printed && vterm_char == cover_char);
@ -1733,13 +1715,13 @@ FChar FVTerm::generateCharacter (const FPoint& pos)
s_ch.attr.bit.reverse = false; s_ch.attr.bit.reverse = false;
s_ch.attr.bit.standout = false; s_ch.attr.bit.standout = false;
if ( s_ch.ch == fc::LowerHalfBlock if ( s_ch.ch[0] == fc::LowerHalfBlock
|| s_ch.ch == fc::UpperHalfBlock || s_ch.ch[0] == fc::UpperHalfBlock
|| s_ch.ch == fc::LeftHalfBlock || s_ch.ch[0] == fc::LeftHalfBlock
|| s_ch.ch == fc::RightHalfBlock || s_ch.ch[0] == fc::RightHalfBlock
|| s_ch.ch == fc::MediumShade || s_ch.ch[0] == fc::MediumShade
|| s_ch.ch == fc::FullBlock ) || s_ch.ch[0] == fc::FullBlock )
s_ch.ch = ' '; s_ch.ch[0] = ' ';
sc = &s_ch; sc = &s_ch;
} }
@ -1860,7 +1842,7 @@ void FVTerm::init()
output_buffer->reserve(TERMINAL_OUTPUT_BUFFER_SIZE + 256); output_buffer->reserve(TERMINAL_OUTPUT_BUFFER_SIZE + 256);
// term_attribute stores the current state of the terminal // term_attribute stores the current state of the terminal
term_attribute.ch = '\0'; term_attribute.ch = { L'\0' };
term_attribute.fg_color = fc::Default; term_attribute.fg_color = fc::Default;
term_attribute.bg_color = fc::Default; term_attribute.bg_color = fc::Default;
term_attribute.attr.byte[0] = 0; term_attribute.attr.byte[0] = 0;
@ -1967,13 +1949,13 @@ void FVTerm::putAreaCharacter ( const FPoint& pos, const FTermArea* area
ch.attr.bit.reverse = false; ch.attr.bit.reverse = false;
ch.attr.bit.standout = false; ch.attr.bit.standout = false;
if ( ch.ch == fc::LowerHalfBlock if ( ch.ch[0] == fc::LowerHalfBlock
|| ch.ch == fc::UpperHalfBlock || ch.ch[0] == fc::UpperHalfBlock
|| ch.ch == fc::LeftHalfBlock || ch.ch[0] == fc::LeftHalfBlock
|| ch.ch == fc::RightHalfBlock || ch.ch[0] == fc::RightHalfBlock
|| ch.ch == fc::MediumShade || ch.ch[0] == fc::MediumShade
|| ch.ch == fc::FullBlock ) || ch.ch[0] == fc::FullBlock )
ch.ch = ' '; ch.ch[0] = ' ';
std::memcpy (&vterm_char, &ch, sizeof(vterm_char)); std::memcpy (&vterm_char, &ch, sizeof(vterm_char));
} }
@ -2084,7 +2066,7 @@ bool FVTerm::clearFullArea (const FTermArea* area, FChar& nc) const
return false; return false;
// Try to clear the terminal rapidly with a control sequence // Try to clear the terminal rapidly with a control sequence
if ( clearTerm (nc.ch) ) if ( clearTerm (nc.ch[0]) )
{ {
nc.attr.bit.printed = true; nc.attr.bit.printed = true;
std::fill_n (vterm->data, area_size, nc); std::fill_n (vterm->data, area_size, nc);
@ -2138,7 +2120,7 @@ bool FVTerm::canClearToEOL (uInt xmin, uInt y)
const auto& ce = TCAP(fc::t_clr_eol); const auto& ce = TCAP(fc::t_clr_eol);
const auto& min_char = vt->data[y * uInt(vt->width) + xmin]; const auto& min_char = vt->data[y * uInt(vt->width) + xmin];
if ( ce && min_char.ch == ' ' ) if ( ce && min_char.ch[0] == ' ' )
{ {
uInt beginning_whitespace = 1; uInt beginning_whitespace = 1;
const bool normal = FTerm::isNormal(min_char); const bool normal = FTerm::isNormal(min_char);
@ -2173,7 +2155,7 @@ bool FVTerm::canClearLeadingWS (uInt& xmin, uInt y)
const auto& cb = TCAP(fc::t_clr_bol); const auto& cb = TCAP(fc::t_clr_bol);
const auto& first_char = vt->data[y * uInt(vt->width)]; const auto& first_char = vt->data[y * uInt(vt->width)];
if ( cb && first_char.ch == ' ' ) if ( cb && first_char.ch[0] == ' ' )
{ {
uInt leading_whitespace = 1; uInt leading_whitespace = 1;
const bool normal = FTerm::isNormal(first_char); const bool normal = FTerm::isNormal(first_char);
@ -2211,7 +2193,7 @@ bool FVTerm::canClearTrailingWS (uInt& xmax, uInt y)
const auto& ce = TCAP(fc::t_clr_eol); const auto& ce = TCAP(fc::t_clr_eol);
const auto& last_char = vt->data[(y + 1) * uInt(vt->width) - 1]; const auto& last_char = vt->data[(y + 1) * uInt(vt->width) - 1];
if ( ce && last_char.ch == ' ' ) if ( ce && last_char.ch[0] == ' ' )
{ {
uInt trailing_whitespace = 1; uInt trailing_whitespace = 1;
const bool normal = FTerm::isNormal(last_char); const bool normal = FTerm::isNormal(last_char);
@ -2245,18 +2227,18 @@ bool FVTerm::skipUnchangedCharacters (uInt& x, uInt xmax, uInt y) const
// Skip characters without changes if it is faster than redrawing // Skip characters without changes if it is faster than redrawing
auto& vt = vterm; auto& vt = vterm;
auto print_char = &vt->data[y * uInt(vt->width) + x]; auto& print_char = vt->data[y * uInt(vt->width) + x];
print_char->attr.bit.printed = true; print_char.attr.bit.printed = true;
if ( print_char->attr.bit.no_changes ) if ( print_char.attr.bit.no_changes )
{ {
uInt count{1}; uInt count{1};
for (uInt i = x + 1; i <= xmax; i++) for (uInt i = x + 1; i <= xmax; i++)
{ {
auto ch = &vt->data[y * uInt(vt->width) + i]; const auto& ch = vt->data[y * uInt(vt->width) + i];
if ( ch->attr.bit.no_changes ) if ( ch.attr.bit.no_changes )
count++; count++;
else else
break; break;
@ -2291,7 +2273,7 @@ void FVTerm::printRange ( uInt xmin, uInt xmax, uInt y
continue; continue;
// Erase character // Erase character
if ( ec && print_char.ch == ' ' ) if ( ec && print_char.ch[0] == ' ' )
{ {
exit_state erase_state = \ exit_state erase_state = \
eraseCharacters(x, xmax, y, draw_trailing_ws); eraseCharacters(x, xmax, y, draw_trailing_ws);
@ -2320,13 +2302,15 @@ inline void FVTerm::replaceNonPrintableFullwidth ( uInt x
if ( x == 0 && isFullWidthPaddingChar(print_char) ) if ( x == 0 && isFullWidthPaddingChar(print_char) )
{ {
print_char.ch = fc::SingleLeftAngleQuotationMark; // print_char.ch[0] = fc::SingleLeftAngleQuotationMark; //
print_char.ch[1] = L'\0';
print_char.attr.bit.fullwidth_padding = false; print_char.attr.bit.fullwidth_padding = false;
} }
else if ( x == uInt(vterm->width - 1) else if ( x == uInt(vterm->width - 1)
&& isFullWidthChar(print_char) ) && isFullWidthChar(print_char) )
{ {
print_char.ch = fc::SingleRightAngleQuotationMark; // print_char.ch[0] = fc::SingleRightAngleQuotationMark; //
print_char.ch[1] = L'\0';
print_char.attr.bit.char_width = 1; print_char.attr.bit.char_width = 1;
} }
} }
@ -2500,7 +2484,7 @@ FVTerm::exit_state FVTerm::eraseCharacters ( uInt& x, uInt xmax, uInt y
const auto& ec = TCAP(fc::t_erase_chars); const auto& ec = TCAP(fc::t_erase_chars);
auto& print_char = vt->data[y * uInt(vt->width) + x]; auto& print_char = vt->data[y * uInt(vt->width) + x];
if ( ! ec || print_char.ch != ' ' ) if ( ! ec || print_char.ch[0] != ' ' )
return not_used; return not_used;
uInt whitespace{1}; uInt whitespace{1};
@ -2590,12 +2574,12 @@ FVTerm::exit_state FVTerm::repeatCharacter (uInt& x, uInt xmax, uInt y) const
const uInt start_pos = x; const uInt start_pos = x;
if ( repetitions > repeat_char_length if ( repetitions > repeat_char_length
&& print_char.ch < 128 ) && print_char.ch[0] < 128 )
{ {
newFontChanges (print_char); newFontChanges (print_char);
charsetChanges (print_char); charsetChanges (print_char);
appendAttributes (print_char); appendAttributes (print_char);
appendOutputBuffer (FTermcap::encodeParameter(rp, print_char.ch, repetitions, 0, 0, 0, 0, 0, 0, 0)); appendOutputBuffer (FTermcap::encodeParameter(rp, print_char.ch[0], repetitions, 0, 0, 0, 0, 0, 0, 0));
term_pos->x_ref() += int(repetitions); term_pos->x_ref() += int(repetitions);
x = x + repetitions - 1; x = x + repetitions - 1;
} }
@ -2739,13 +2723,14 @@ void FVTerm::printPaddingCharacter (FTermArea* area, const FChar& term_char)
if ( FTerm::getEncoding() == fc::UTF8 ) if ( FTerm::getEncoding() == fc::UTF8 )
{ {
pc.ch = 0; pc.ch = { L'\0' };
pc.attr.bit.fullwidth_padding = true; pc.attr.bit.fullwidth_padding = true;
pc.attr.bit.char_width = 0; pc.attr.bit.char_width = 0;
} }
else else
{ {
pc.ch = '.'; pc.ch[0] = L'.';
pc.ch[1] = L'\0';
pc.attr.bit.char_width = 1; pc.attr.bit.char_width = 1;
} }
@ -2917,20 +2902,20 @@ inline void FVTerm::newFontChanges (FChar& next_char)
if ( ! FTerm::isNewFont() ) if ( ! FTerm::isNewFont() )
return; return;
if ( next_char.ch == fc::LowerHalfBlock ) if ( next_char.ch[0] == fc::LowerHalfBlock )
{ {
next_char.ch = fc::UpperHalfBlock; next_char.ch[0] = fc::UpperHalfBlock;
next_char.attr.bit.reverse = true; next_char.attr.bit.reverse = true;
} }
else if ( isReverseNewFontchar(next_char.ch) ) else if ( isReverseNewFontchar(next_char.ch[0]) )
next_char.attr.bit.reverse = true; // Show in reverse video next_char.attr.bit.reverse = true; // Show in reverse video
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FVTerm::charsetChanges (FChar& next_char) inline void FVTerm::charsetChanges (FChar& next_char)
{ {
const wchar_t& ch = next_char.ch; const wchar_t& ch = next_char.ch[0];
next_char.encoded_char = ch; next_char.encoded_char[0] = ch;
if ( FTerm::getEncoding() == fc::UTF8 ) if ( FTerm::getEncoding() == fc::UTF8 )
return; return;
@ -2942,11 +2927,11 @@ inline void FVTerm::charsetChanges (FChar& next_char)
if ( ch_enc == 0 ) if ( ch_enc == 0 )
{ {
next_char.encoded_char = wchar_t(FTerm::charEncode(ch, fc::ASCII)); next_char.encoded_char[0] = wchar_t(FTerm::charEncode(ch, fc::ASCII));
return; return;
} }
next_char.encoded_char = ch_enc; next_char.encoded_char[0] = ch_enc;
if ( FTerm::getEncoding() == fc::VT100 ) if ( FTerm::getEncoding() == fc::VT100 )
next_char.attr.bit.alt_charset = true; next_char.attr.bit.alt_charset = true;
@ -2960,10 +2945,10 @@ inline void FVTerm::charsetChanges (FChar& next_char)
if ( FTerm::isXTerminal() && ch_enc < 0x20 ) // Character 0x00..0x1f if ( FTerm::isXTerminal() && ch_enc < 0x20 ) // Character 0x00..0x1f
{ {
if ( FTerm::hasUTF8() ) if ( FTerm::hasUTF8() )
next_char.encoded_char = int(FTerm::charEncode(ch, fc::ASCII)); next_char.encoded_char[0] = int(FTerm::charEncode(ch, fc::ASCII));
else else
{ {
next_char.encoded_char += 0x5f; next_char.encoded_char[0] += 0x5f;
next_char.attr.bit.alt_charset = true; next_char.attr.bit.alt_charset = true;
} }
} }
@ -2992,14 +2977,14 @@ inline void FVTerm::appendChar (FChar& next_char) const
charsetChanges (next_char); charsetChanges (next_char);
appendAttributes (next_char); appendAttributes (next_char);
characterFilter (next_char); characterFilter (next_char);
appendOutputBuffer (next_char.encoded_char); appendOutputBuffer (next_char.encoded_char[0]);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FVTerm::appendAttributes (FChar& next_attr) const inline void FVTerm::appendAttributes (FChar& next_attr) const
{ {
// generate attribute string for the next character // generate attribute string for the next character
const auto attr_str = FTerm::changeAttribute (term_attribute, next_attr); const auto& attr_str = FTerm::changeAttribute (term_attribute, next_attr);
if ( attr_str ) if ( attr_str )
appendOutputBuffer (attr_str); appendOutputBuffer (attr_str);
@ -3069,8 +3054,8 @@ inline void FVTerm::characterFilter (FChar& next_char)
{ {
charSubstitution& sub_map = fterm->getCharSubstitutionMap(); charSubstitution& sub_map = fterm->getCharSubstitutionMap();
if ( sub_map.find(next_char.encoded_char) != sub_map.end() ) if ( sub_map.find(next_char.encoded_char[0]) != sub_map.end() )
next_char.encoded_char = sub_map[next_char.encoded_char]; next_char.encoded_char[0] = sub_map[next_char.encoded_char[0]];
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -981,10 +981,7 @@ void FWidget::show()
if ( show_root_widget && show_root_widget == this ) if ( show_root_widget && show_root_widget == this )
{ {
finishDrawing(); finishDrawing();
forceTerminalUpdate();
if ( processTerminalUpdate() )
flush();
show_root_widget = nullptr; show_root_widget = nullptr;
} }
@ -1978,7 +1975,7 @@ void FWidget::drawWindows() const
{ {
// redraw windows // redraw windows
FChar default_char{}; FChar default_char{};
default_char.ch = ' '; default_char.ch[0] = ' ';
default_char.fg_color = fc::Black; default_char.fg_color = fc::Black;
default_char.bg_color = fc::Black; default_char.bg_color = fc::Black;
default_char.attr.byte[0] = 0; default_char.attr.byte[0] = 0;

View File

@ -183,7 +183,7 @@
/* Define to the full name and version of this package. */ /* Define to the full name and version of this package. */
#ifndef F_PACKAGE_STRING #ifndef F_PACKAGE_STRING
#define F_PACKAGE_STRING "finalcut 0.7.0" #define F_PACKAGE_STRING "finalcut 0.7.1"
#endif #endif
/* Define to the one symbol short name of this package. */ /* Define to the one symbol short name of this package. */
@ -198,7 +198,7 @@
/* Define to the version of this package. */ /* Define to the version of this package. */
#ifndef F_PACKAGE_VERSION #ifndef F_PACKAGE_VERSION
#define F_PACKAGE_VERSION "0.7.0" #define F_PACKAGE_VERSION "0.7.1"
#endif #endif
/* Define to 1 if you have the ANSI C header files. */ /* Define to 1 if you have the ANSI C header files. */
@ -230,7 +230,7 @@
/* Version number of package */ /* Version number of package */
#ifndef F_VERSION #ifndef F_VERSION
#define F_VERSION "0.7.0" #define F_VERSION "0.7.1"
#endif #endif
/* Define to 1 if on MINIX. */ /* Define to 1 if on MINIX. */

View File

@ -171,7 +171,6 @@ class FString
// Methods // Methods
std::size_t getLength() const; std::size_t getLength() const;
std::size_t getUTF8length() const;
std::size_t capacity() const; std::size_t capacity() const;
iterator begin(); iterator begin();

View File

@ -31,6 +31,9 @@
#include <sys/types.h> #include <sys/types.h>
#include <cstddef> #include <cstddef>
#include <cstring>
#include <array>
#include <functional> #include <functional>
#include <limits> #include <limits>
#include <unordered_map> #include <unordered_map>
@ -150,13 +153,17 @@ union attribute
uInt8 byte[4]; uInt8 byte[4];
}; };
static constexpr uInt UNICODE_MAX = 5;
typedef std::array<wchar_t, UNICODE_MAX> FUnicode;
typedef struct typedef struct
{ {
wchar_t ch; // Character code FUnicode ch; // Character code
wchar_t encoded_char; // Encoded output character FUnicode encoded_char; // Encoded output character
FColor fg_color; // Foreground color FColor fg_color; // Foreground color
FColor bg_color; // Background color FColor bg_color; // Background color
attribute attr; // Attributes attribute attr; // Attributes
} FChar; } FChar;
@ -189,9 +196,9 @@ FKeyName;
// FChar operator functions // FChar operator functions
//---------------------------------------------------------------------- //----------------------------------------------------------------------
constexpr bool operator == (const FChar& lhs, const FChar& rhs) inline bool operator == (const FChar& lhs, const FChar& rhs)
{ {
return lhs.ch == rhs.ch return operator == (lhs.ch, rhs.ch)
&& lhs.fg_color == rhs.fg_color && lhs.fg_color == rhs.fg_color
&& lhs.bg_color == rhs.bg_color && lhs.bg_color == rhs.bg_color
&& lhs.attr.byte[0] == rhs.attr.byte[0] && lhs.attr.byte[0] == rhs.attr.byte[0]
@ -201,7 +208,7 @@ constexpr bool operator == (const FChar& lhs, const FChar& rhs)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
constexpr bool operator != (const FChar& lhs, const FChar& rhs) inline bool operator != (const FChar& lhs, const FChar& rhs)
{ {
return ! ( lhs == rhs ); return ! ( lhs == rhs );
} }

View File

@ -262,10 +262,10 @@ class FVTerm
int printf (const FString&, Args&&...); int printf (const FString&, Args&&...);
int print (const FString&); int print (const FString&);
int print (FTermArea*, const FString&); int print (FTermArea*, const FString&);
int print (const FTermBuffer&);
int print (FTermArea*, const FTermBuffer&);
int print (const std::vector<FChar>&); int print (const std::vector<FChar>&);
int print (FTermArea*, const std::vector<FChar>&); int print (FTermArea*, const std::vector<FChar>&);
int print (const FTermBuffer&);
int print (FTermArea*, const FTermBuffer&);
int print (wchar_t); int print (wchar_t);
int print (FTermArea*, wchar_t); int print (FTermArea*, wchar_t);
int print (FChar&); int print (FChar&);
@ -317,6 +317,7 @@ class FVTerm
void scrollAreaForward (FTermArea*) const; void scrollAreaForward (FTermArea*) const;
void scrollAreaReverse (FTermArea*) const; void scrollAreaReverse (FTermArea*) const;
void clearArea (FTermArea*, int = ' ') const; void clearArea (FTermArea*, int = ' ') const;
void forceTerminalUpdate() const;
bool processTerminalUpdate() const; bool processTerminalUpdate() const;
static void startDrawing(); static void startDrawing();
static void finishDrawing(); static void finishDrawing();
@ -340,7 +341,7 @@ class FVTerm
// Constants // Constants
// Buffer size for character output on the terminal // Buffer size for character output on the terminal
static constexpr uInt TERMINAL_OUTPUT_BUFFER_SIZE = 131072; static constexpr uInt TERMINAL_OUTPUT_BUFFER_SIZE = 131072;
static constexpr int max_skip = 20; static constexpr int max_skip = 2;
// Methods // Methods
void resetTextAreaToDefault ( const FTermArea* void resetTextAreaToDefault ( const FTermArea*
@ -441,8 +442,9 @@ class FVTerm
static timeval last_term_size_check; static timeval last_term_size_check;
static bool draw_completed; static bool draw_completed;
static bool no_terminal_updates; static bool no_terminal_updates;
static uInt64 term_size_check_timeout; static bool force_terminal_update;
static int skipped_terminal_update; static int skipped_terminal_update;
static uInt64 term_size_check_timeout;
static uInt erase_char_length; static uInt erase_char_length;
static uInt repeat_char_length; static uInt repeat_char_length;
static uInt clr_bol_length; static uInt clr_bol_length;

View File

@ -107,12 +107,6 @@
#include "final/ftypes.h" #include "final/ftypes.h"
#include "final/fvterm.h" #include "final/fvterm.h"
// Old callback macros (deprecated)
#define F_FUNCTION_CALLBACK(h) (h), this, nullptr
#define F_FUNCTION_CALLBACK_DATA(h) (h), this
#define F_METHOD_CALLBACK(i,h) (i), (h), this, nullptr
#define F_METHOD_CALLBACK_DATA(i,h) (i), (h), this
namespace finalcut namespace finalcut
{ {

View File

@ -1085,7 +1085,7 @@ void FOptiAttrTest::vt100Test()
CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to)
, CSI "0m\017$<2>" ); , CSI "0m\017$<2>" );
CPPUNIT_ASSERT ( from == to ); CPPUNIT_ASSERT ( from == to );
CPPUNIT_ASSERT ( to.encoded_char == ' ' ); CPPUNIT_ASSERT ( to.encoded_char[0] == ' ' );
CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 );
// Invisible off (with default colors) // Invisible off (with default colors)
@ -2028,7 +2028,7 @@ void FOptiAttrTest::rxvtTest()
CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to)
, CSI "0m\017" ); , CSI "0m\017" );
CPPUNIT_ASSERT ( from == to ); CPPUNIT_ASSERT ( from == to );
CPPUNIT_ASSERT ( to.encoded_char == ' ' ); CPPUNIT_ASSERT ( to.encoded_char[0] == ' ' );
CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 );
// Invisible off (with default colors) // Invisible off (with default colors)
@ -2498,7 +2498,7 @@ void FOptiAttrTest::linuxTest()
CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to)
, CSI "0m\017" ); , CSI "0m\017" );
CPPUNIT_ASSERT ( from == to ); CPPUNIT_ASSERT ( from == to );
CPPUNIT_ASSERT ( to.encoded_char == ' ' ); CPPUNIT_ASSERT ( to.encoded_char[0] == ' ' );
CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 );
// Invisible off (with default colors) // Invisible off (with default colors)
@ -2979,7 +2979,7 @@ void FOptiAttrTest::puttyTest()
CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to)
, CSI "0m\017" ); , CSI "0m\017" );
CPPUNIT_ASSERT ( from == to ); CPPUNIT_ASSERT ( from == to );
CPPUNIT_ASSERT ( to.encoded_char == ' ' ); CPPUNIT_ASSERT ( to.encoded_char[0] == ' ' );
CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 );
// Invisible off (with default colors) // Invisible off (with default colors)
@ -3450,7 +3450,7 @@ void FOptiAttrTest::teratermTest()
CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to)
, CSI "0m\017$<2>" ); , CSI "0m\017$<2>" );
CPPUNIT_ASSERT ( from == to ); CPPUNIT_ASSERT ( from == to );
CPPUNIT_ASSERT ( to.encoded_char == ' ' ); CPPUNIT_ASSERT ( to.encoded_char[0] == ' ' );
CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 );
// Invisible off (with default colors) // Invisible off (with default colors)
@ -3905,7 +3905,7 @@ void FOptiAttrTest::ibmColorTest()
CPPUNIT_ASSERT ( from != to ); CPPUNIT_ASSERT ( from != to );
CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to), "" ); CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to), "" );
CPPUNIT_ASSERT ( from == to ); CPPUNIT_ASSERT ( from == to );
CPPUNIT_ASSERT ( to.encoded_char == ' ' ); CPPUNIT_ASSERT ( to.encoded_char[0] == ' ' );
CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 );
// Invisible off (with default colors) // Invisible off (with default colors)

View File

@ -162,7 +162,6 @@ void FStringTest::noArgumentTest()
CPPUNIT_ASSERT ( empty.isEmpty() ); CPPUNIT_ASSERT ( empty.isEmpty() );
CPPUNIT_ASSERT ( empty.getLength() == 0 ); CPPUNIT_ASSERT ( empty.getLength() == 0 );
CPPUNIT_ASSERT ( empty.capacity() == 0 ); CPPUNIT_ASSERT ( empty.capacity() == 0 );
CPPUNIT_ASSERT ( empty.getUTF8length() == 0 );
CPPUNIT_ASSERT ( empty.wc_str() == nullptr ); CPPUNIT_ASSERT ( empty.wc_str() == nullptr );
CPPUNIT_ASSERT ( empty.c_str() == nullptr ); CPPUNIT_ASSERT ( empty.c_str() == nullptr );
CPPUNIT_ASSERT_EQUAL ( empty.toString(), std::string() ); CPPUNIT_ASSERT_EQUAL ( empty.toString(), std::string() );
@ -657,7 +656,6 @@ void FStringTest::equalTest()
constexpr char cstr[] = "abc"; constexpr char cstr[] = "abc";
CPPUNIT_ASSERT ( str == cstr ); CPPUNIT_ASSERT ( str == cstr );
CPPUNIT_ASSERT ( str.getLength() == 3 ); CPPUNIT_ASSERT ( str.getLength() == 3 );
CPPUNIT_ASSERT ( str.getUTF8length() == 3 );
CPPUNIT_ASSERT ( str.capacity() == 18 ); CPPUNIT_ASSERT ( str.capacity() == 18 );
CPPUNIT_ASSERT ( strncmp(cstr, str.c_str(), 3) == 0 ); CPPUNIT_ASSERT ( strncmp(cstr, str.c_str(), 3) == 0 );
@ -706,8 +704,6 @@ void FStringTest::notEqualTest()
CPPUNIT_ASSERT ( strlen(s1.c_str()) == 3 ); CPPUNIT_ASSERT ( strlen(s1.c_str()) == 3 );
CPPUNIT_ASSERT ( s2.getLength() == 3 ); CPPUNIT_ASSERT ( s2.getLength() == 3 );
CPPUNIT_ASSERT ( strlen(s2.c_str()) == 6 ); CPPUNIT_ASSERT ( strlen(s2.c_str()) == 6 );
CPPUNIT_ASSERT ( s1.getUTF8length() == 3 );
CPPUNIT_ASSERT ( s2.getUTF8length() == 3 );
CPPUNIT_ASSERT ( s1.capacity() == 18 ); CPPUNIT_ASSERT ( s1.capacity() == 18 );
CPPUNIT_ASSERT ( s2.capacity() == 18 ); CPPUNIT_ASSERT ( s2.capacity() == 18 );
CPPUNIT_ASSERT ( strncmp(cstr, s1.c_str(), 3) != 0 ); CPPUNIT_ASSERT ( strncmp(cstr, s1.c_str(), 3) != 0 );