VTerm marks printed characters for a correct determination of unchanged characters

This commit is contained in:
Markus Gans 2016-12-22 02:02:40 +01:00
parent b9f3be782f
commit c4a8886da2
5 changed files with 120 additions and 64 deletions

View File

@ -1,3 +1,7 @@
2016-12-22 Markus Gans <guru.mail@muenster.de>
* VTerm marks printed characters for a correct determination
of unchanged characters
2016-12-18 Markus Gans <guru.mail@muenster.de> 2016-12-18 Markus Gans <guru.mail@muenster.de>
* Only perform VTerm updates on terminal updates * Only perform VTerm updates on terminal updates
* Skipping the print of characters without changes * Skipping the print of characters without changes

View File

@ -958,12 +958,6 @@ void FDialog::onWindowRaised (FEvent*)
++iter; ++iter;
} }
} }
if ( ! window_list )
return;
if ( window_list->empty() )
return;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -56,7 +56,7 @@ class FOptiAttr
uChar trans_shadow : 1; // transparent shadow uChar trans_shadow : 1; // transparent shadow
uChar inherit_bg : 1; // inherit background uChar inherit_bg : 1; // inherit background
uChar no_changes : 1; // no changes required uChar no_changes : 1; // no changes required
uChar restored : 1; // restored VTerm character uChar printed : 1; // is printed to VTerm
uChar : 6; // padding bits uChar : 6; // padding bits
} char_data; } char_data;

View File

@ -107,7 +107,7 @@ void FVTerm::setTermXY (register int x, register int y)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FVTerm::clearTerm (int fillchar) bool FVTerm::clearTerm (int fillchar)
{ {
// Clear the real terminal and put cursor at home // Clear the real terminal and put cursor at home
char*& cl = tcap[fc::t_clear_screen].string; char*& cl = tcap[fc::t_clear_screen].string;
@ -121,17 +121,10 @@ void FVTerm::clearTerm (int fillchar)
if ( ! ( (cl || cd || cb) && (normal || ut) ) if ( ! ( (cl || cd || cb) && (normal || ut) )
|| fillchar != ' ' ) || fillchar != ' ' )
{ {
for (int i=0; i < vdesktop->height; i++) return false;
{
vdesktop->changes[i].xmin = 0;
vdesktop->changes[i].xmax = uInt(vdesktop->width) - 1;
vdesktop->changes[i].trans_count = 0;
}
vdesktop->has_changes = true;
setTermXY (0,0);
} }
else if ( cl )
if ( cl )
{ {
appendOutputBuffer (cl); appendOutputBuffer (cl);
term_pos->setPoint(0,0); term_pos->setPoint(0,0);
@ -148,7 +141,7 @@ void FVTerm::clearTerm (int fillchar)
for (int i=0; i < getLineNumber(); i++) for (int i=0; i < getLineNumber(); i++)
{ {
setTermXY (0,i); setTermXY (0, i);
appendOutputBuffer (cb); appendOutputBuffer (cb);
} }
@ -156,6 +149,7 @@ void FVTerm::clearTerm (int fillchar)
} }
flush_out(); flush_out();
return true;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -391,6 +385,7 @@ void FVTerm::updateTerminalLine (uInt y)
{ {
appendAttributes (min_char); appendAttributes (min_char);
appendOutputBuffer (ce); appendOutputBuffer (ce);
markAsPrinted (xmin, uInt(vt->width - 1), y);
} }
else else
{ {
@ -398,17 +393,18 @@ void FVTerm::updateTerminalLine (uInt y)
{ {
appendAttributes (first_char); appendAttributes (first_char);
appendOutputBuffer (cb); appendOutputBuffer (cb);
markAsPrinted (0, xmin, y);
} }
for (uInt x=xmin; x <= xmax; x++) for (uInt x=xmin; x <= xmax; x++)
{ {
char_data* print_char; char_data* print_char;
print_char = &vt->text[y * uInt(vt->width) + x]; print_char = &vt->text[y * uInt(vt->width) + x];
print_char->printed = true;
// skip character with no changes // skip character with no changes
if ( ! terminal_update_pending if ( ! terminal_update_pending
&& print_char->no_changes && print_char->no_changes )
&& ! print_char->restored )
{ {
uInt count = 1; uInt count = 1;
@ -416,7 +412,7 @@ void FVTerm::updateTerminalLine (uInt y)
{ {
char_data* ch = &vt->text[y * uInt(vt->width) + i]; char_data* ch = &vt->text[y * uInt(vt->width) + i];
if ( ch->no_changes && ! ch->restored ) if ( ch->no_changes )
count++; count++;
else else
break; break;
@ -446,25 +442,37 @@ void FVTerm::updateTerminalLine (uInt y)
break; break;
} }
if ( whitespace > uInt(erase_ch_length) + uInt(cursor_addres_lengths) if ( whitespace == 1 )
&& (ut || normal) )
{ {
appendAttributes (print_char); appendCharacter (print_char);
appendOutputBuffer (tparm(ec, whitespace)); markAsPrinted (x, y);
if ( x + whitespace - 1 < xmax || draw_tailing_ws )
setTermXY (int(x + whitespace), int(y));
else
break;
x = x + whitespace - 1;
} }
else else
{ {
x--; uInt start_pos = x;
for (uInt i=0; i < whitespace; i++, x++) if ( whitespace > uInt(erase_ch_length) + uInt(cursor_addres_lengths)
appendCharacter (print_char); && (ut || normal) )
{
appendAttributes (print_char);
appendOutputBuffer (tparm(ec, whitespace));
if ( x + whitespace - 1 < xmax || draw_tailing_ws )
setTermXY (int(x + whitespace), int(y));
else
break;
x = x + whitespace - 1;
}
else
{
x--;
for (uInt i=0; i < whitespace; i++, x++)
appendCharacter (print_char);
}
markAsPrinted (start_pos, x, y);
} }
} }
else if ( rp ) // Repeat one character n-fold else if ( rp ) // Repeat one character n-fold
@ -481,32 +489,48 @@ void FVTerm::updateTerminalLine (uInt y)
break; break;
} }
if ( repetitions > uInt(repeat_char_length) if ( repetitions == 1 )
&& print_char->code < 128 )
{ {
newFontChanges (print_char); appendCharacter (print_char);
charsetChanges (print_char); markAsPrinted (x, y);
appendAttributes (print_char);
appendOutputBuffer (tparm(rp, print_char->code, repetitions));
term_pos->x_ref() += short(repetitions);
x = x + repetitions - 1;
} }
else else
{ {
x--; uInt start_pos = x;
for (uInt i=0; i < repetitions; i++, x++) if ( repetitions > uInt(repeat_char_length)
appendCharacter (print_char); && print_char->code < 128 )
{
newFontChanges (print_char);
charsetChanges (print_char);
appendAttributes (print_char);
appendOutputBuffer (tparm(rp, print_char->code, repetitions));
term_pos->x_ref() += short(repetitions);
x = x + repetitions - 1;
}
else
{
x--;
for (uInt i=0; i < repetitions; i++, x++)
appendCharacter (print_char);
}
markAsPrinted (start_pos, x, y);
} }
} }
else else // General character output
{
appendCharacter (print_char); appendCharacter (print_char);
markAsPrinted (x, y);
}
} }
if ( draw_tailing_ws ) if ( draw_tailing_ws )
{ {
appendAttributes (last_char); appendAttributes (last_char);
appendOutputBuffer (ce); appendOutputBuffer (ce);
markAsPrinted (xmax+1, uInt(vt->width - 1), y);
} }
} }
@ -801,7 +825,7 @@ int FVTerm::print (term_area* area, FString& s)
nc.trans_shadow = next_attribute.trans_shadow; nc.trans_shadow = next_attribute.trans_shadow;
nc.inherit_bg = next_attribute.inherit_bg; nc.inherit_bg = next_attribute.inherit_bg;
nc.no_changes = false; nc.no_changes = false;
nc.restored = false; nc.printed = false;
if ( area if ( area
&& area->cursor_x > 0 && area->cursor_x > 0
@ -917,7 +941,7 @@ int FVTerm::print (term_area* area, register int c)
nc.trans_shadow = next_attribute.trans_shadow; nc.trans_shadow = next_attribute.trans_shadow;
nc.inherit_bg = next_attribute.inherit_bg; nc.inherit_bg = next_attribute.inherit_bg;
nc.no_changes = false; nc.no_changes = false;
nc.restored = false; nc.printed = false;
if ( area->cursor_x > 0 if ( area->cursor_x > 0
&& area->cursor_y > 0 && area->cursor_y > 0
@ -1455,7 +1479,6 @@ void FVTerm::restoreVTerm (int x, int y, int w, int h)
} }
} }
sc->restored = true;
std::memcpy (tc, sc, sizeof(char_data)); std::memcpy (tc, sc, sizeof(char_data));
if ( short(vterm->changes[y+ty].xmin) > x ) if ( short(vterm->changes[y+ty].xmin) > x )
@ -1541,7 +1564,7 @@ FVTerm::covered_state FVTerm::isCovered ( int x, int y
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FVTerm::updateVTerm() void FVTerm::updateVTerm()
{ {
// Update data on VTerm // Updates the character data from all areas to VTerm
if ( vdesktop && vdesktop->has_changes ) if ( vdesktop && vdesktop->has_changes )
{ {
@ -1667,7 +1690,7 @@ void FVTerm::updateVTerm (term_area* area)
|| ch.code == fc::FullBlock ) || ch.code == fc::FullBlock )
ch.code = ' '; ch.code = ' ';
ch.no_changes = bool(! tc->restored && *tc == ch); ch.no_changes = bool(tc->printed && *tc == ch);
std::memcpy (tc, &ch, sizeof(char_data)); std::memcpy (tc, &ch, sizeof(char_data));
} }
else if ( ac->transparent ) // transparent else if ( ac->transparent ) // transparent
@ -1675,7 +1698,7 @@ void FVTerm::updateVTerm (term_area* area)
// restore one character on vterm // restore one character on vterm
char_data ch; char_data ch;
ch = getCoveredCharacter (gx+1 - ol, gy+1, area->widget); ch = getCoveredCharacter (gx+1 - ol, gy+1, area->widget);
ch.no_changes = bool(! tc->restored && *tc == ch); ch.no_changes = bool(tc->printed && *tc == ch);
std::memcpy (tc, &ch, sizeof(char_data)); std::memcpy (tc, &ch, sizeof(char_data));
} }
else // not transparent else // not transparent
@ -1698,7 +1721,7 @@ void FVTerm::updateVTerm (term_area* area)
|| ch.code == fc::FullBlock ) || ch.code == fc::FullBlock )
ch.code = ' '; ch.code = ' ';
ch.no_changes = bool(! tc->restored && *tc == ch); ch.no_changes = bool(tc->printed && *tc == ch);
std::memcpy (tc, &ch, sizeof(char_data)); std::memcpy (tc, &ch, sizeof(char_data));
} }
else if ( ac->inherit_bg ) else if ( ac->inherit_bg )
@ -1708,12 +1731,12 @@ void FVTerm::updateVTerm (term_area* area)
std::memcpy (&ch, ac, sizeof(char_data)); std::memcpy (&ch, ac, sizeof(char_data));
cc = getCoveredCharacter (gx+1 - ol, gy+1, area->widget); cc = getCoveredCharacter (gx+1 - ol, gy+1, area->widget);
ch.bg_color = cc.bg_color; ch.bg_color = cc.bg_color;
ch.no_changes = bool(*tc == ch); ch.no_changes = bool(tc->printed && *tc == ch);
std::memcpy (tc, &ch, sizeof(char_data)); std::memcpy (tc, &ch, sizeof(char_data));
} }
else // default else // default
{ {
if ( ! tc->restored && *tc == *ac ) if ( tc->printed && *tc == *ac )
{ {
std::memcpy (tc, ac, sizeof(char_data)); std::memcpy (tc, ac, sizeof(char_data));
tc->no_changes = true; tc->no_changes = true;
@ -1731,7 +1754,6 @@ void FVTerm::updateVTerm (term_area* area)
else if ( ! modified ) else if ( ! modified )
line_xmin++; // don't update covered character line_xmin++; // don't update covered character
tc->restored = false;
} }
_xmin = ax + line_xmin - ol; _xmin = ax + line_xmin - ol;
@ -2204,8 +2226,23 @@ void FVTerm::clearArea (term_area* area, int fillchar)
if ( area == vdesktop ) if ( area == vdesktop )
{ {
std::fill_n (vterm->text, area_size, nc); if ( clearTerm (fillchar) )
clearTerm (fillchar); {
nc.printed = true;
std::fill_n (vterm->text, area_size, nc);
}
else
{
for (int i=0; i < vdesktop->height; i++)
{
vdesktop->changes[i].xmin = 0;
vdesktop->changes[i].xmax = uInt(vdesktop->width) - 1;
vdesktop->changes[i].trans_count = 0;
}
vdesktop->has_changes = true;
}
return; return;
} }
} }
@ -2217,10 +2254,13 @@ void FVTerm::clearArea (term_area* area, int fillchar)
for (int y=0; y < area->height; y++) for (int y=0; y < area->height; y++)
{ {
int pos = y * total_width; int pos = y * total_width;
// area
std::fill_n (&area->text[pos], total_width, nc); std::fill_n (&area->text[pos], total_width, nc);
// right shadow
std::fill_n (&area->text[pos+area->width], area->right_shadow, t_char); std::fill_n (&area->text[pos+area->width], area->right_shadow, t_char);
} }
// bottom shadow
for (int y=0; y < area->bottom_shadow; y++) for (int y=0; y < area->bottom_shadow; y++)
{ {
int pos = total_width * (y + area->height); int pos = total_width * (y + area->height);
@ -2230,7 +2270,6 @@ void FVTerm::clearArea (term_area* area, int fillchar)
for (int i=0; i < area->height; i++) for (int i=0; i < area->height; i++)
{ {
area->changes[i].xmin = 0; area->changes[i].xmin = 0;
area->changes[i].xmax = w - 1; area->changes[i].xmax = w - 1;
@ -2486,7 +2525,7 @@ void FVTerm::init()
term_attribute.trans_shadow = \ term_attribute.trans_shadow = \
term_attribute.inherit_bg = \ term_attribute.inherit_bg = \
term_attribute.no_changes = \ term_attribute.no_changes = \
term_attribute.restored = false; term_attribute.printed = false;
// next_attribute contains the state of the next printed character // next_attribute contains the state of the next printed character
std::memcpy (&next_attribute, &term_attribute, sizeof(char_data)); std::memcpy (&next_attribute, &term_attribute, sizeof(char_data));
@ -2529,3 +2568,20 @@ void FVTerm::finish()
if ( term_pos ) if ( term_pos )
delete term_pos; delete term_pos;
} }
//----------------------------------------------------------------------
inline void FVTerm::markAsPrinted (uInt pos, uInt line)
{
// Marks a character as printed
vterm->text[line * uInt(vterm->width) + pos].printed = true;
}
//----------------------------------------------------------------------
inline void FVTerm::markAsPrinted (uInt from, uInt to, uInt line)
{
// Marks characters in the specified range [from .. to] as printed
for (uInt x=from; x <= to; x++)
vterm->text[line * uInt(vterm->width) + x].printed = true;
}

View File

@ -94,7 +94,7 @@ class FVTerm : public FObject, public FTerm
// Mutators // Mutators
static void setTermXY (register int, register int); static void setTermXY (register int, register int);
static void clearTerm (int = ' '); static bool clearTerm (int = ' ');
static bool hideCursor (bool); static bool hideCursor (bool);
static bool hideCursor(); static bool hideCursor();
static bool showCursor(); static bool showCursor();
@ -330,6 +330,8 @@ class FVTerm : public FObject, public FTerm
// Methods // Methods
void init(); void init();
void finish(); void finish();
static void markAsPrinted (uInt, uInt);
static void markAsPrinted (uInt, uInt, uInt);
// Data Members // Data Members
static std::queue<int>* output_buffer; static std::queue<int>* output_buffer;