diff --git a/ChangeLog b/ChangeLog index 2c55867a..9062fa38 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2016-12-22 Markus Gans + * VTerm marks printed characters for a correct determination + of unchanged characters + 2016-12-18 Markus Gans * Only perform VTerm updates on terminal updates * Skipping the print of characters without changes diff --git a/src/fdialog.cpp b/src/fdialog.cpp index 1259b2fe..4df21dce 100644 --- a/src/fdialog.cpp +++ b/src/fdialog.cpp @@ -958,12 +958,6 @@ void FDialog::onWindowRaised (FEvent*) ++iter; } } - - if ( ! window_list ) - return; - - if ( window_list->empty() ) - return; } //---------------------------------------------------------------------- diff --git a/src/foptiattr.h b/src/foptiattr.h index f7f2f689..74772e79 100644 --- a/src/foptiattr.h +++ b/src/foptiattr.h @@ -56,7 +56,7 @@ class FOptiAttr uChar trans_shadow : 1; // transparent shadow uChar inherit_bg : 1; // inherit background uChar no_changes : 1; // no changes required - uChar restored : 1; // restored VTerm character + uChar printed : 1; // is printed to VTerm uChar : 6; // padding bits } char_data; diff --git a/src/fvterm.cpp b/src/fvterm.cpp index bc274380..59bf447e 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -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 char*& cl = tcap[fc::t_clear_screen].string; @@ -121,17 +121,10 @@ void FVTerm::clearTerm (int fillchar) if ( ! ( (cl || cd || cb) && (normal || ut) ) || fillchar != ' ' ) { - 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; - setTermXY (0,0); + return false; } - else if ( cl ) + + if ( cl ) { appendOutputBuffer (cl); term_pos->setPoint(0,0); @@ -148,7 +141,7 @@ void FVTerm::clearTerm (int fillchar) for (int i=0; i < getLineNumber(); i++) { - setTermXY (0,i); + setTermXY (0, i); appendOutputBuffer (cb); } @@ -156,6 +149,7 @@ void FVTerm::clearTerm (int fillchar) } flush_out(); + return true; } //---------------------------------------------------------------------- @@ -391,6 +385,7 @@ void FVTerm::updateTerminalLine (uInt y) { appendAttributes (min_char); appendOutputBuffer (ce); + markAsPrinted (xmin, uInt(vt->width - 1), y); } else { @@ -398,17 +393,18 @@ void FVTerm::updateTerminalLine (uInt y) { appendAttributes (first_char); appendOutputBuffer (cb); + markAsPrinted (0, xmin, y); } for (uInt x=xmin; x <= xmax; x++) { char_data* print_char; print_char = &vt->text[y * uInt(vt->width) + x]; + print_char->printed = true; // skip character with no changes - if ( ! terminal_update_pending - && print_char->no_changes - && ! print_char->restored ) + if ( ! terminal_update_pending + && print_char->no_changes ) { uInt count = 1; @@ -416,7 +412,7 @@ void FVTerm::updateTerminalLine (uInt y) { char_data* ch = &vt->text[y * uInt(vt->width) + i]; - if ( ch->no_changes && ! ch->restored ) + if ( ch->no_changes ) count++; else break; @@ -446,25 +442,37 @@ void FVTerm::updateTerminalLine (uInt y) break; } - if ( whitespace > uInt(erase_ch_length) + uInt(cursor_addres_lengths) - && (ut || normal) ) + if ( whitespace == 1 ) { - 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; + appendCharacter (print_char); + markAsPrinted (x, y); } else { - x--; + uInt start_pos = x; - for (uInt i=0; i < whitespace; i++, x++) - appendCharacter (print_char); + if ( whitespace > uInt(erase_ch_length) + uInt(cursor_addres_lengths) + && (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 @@ -481,32 +489,48 @@ void FVTerm::updateTerminalLine (uInt y) break; } - if ( repetitions > uInt(repeat_char_length) - && print_char->code < 128 ) + if ( repetitions == 1 ) { - 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; + appendCharacter (print_char); + markAsPrinted (x, y); } else { - x--; + uInt start_pos = x; - for (uInt i=0; i < repetitions; i++, x++) - appendCharacter (print_char); + if ( repetitions > uInt(repeat_char_length) + && 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); + markAsPrinted (x, y); + } } if ( draw_tailing_ws ) { appendAttributes (last_char); 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.inherit_bg = next_attribute.inherit_bg; nc.no_changes = false; - nc.restored = false; + nc.printed = false; if ( area && 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.inherit_bg = next_attribute.inherit_bg; nc.no_changes = false; - nc.restored = false; + nc.printed = false; if ( area->cursor_x > 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)); if ( short(vterm->changes[y+ty].xmin) > x ) @@ -1541,7 +1564,7 @@ FVTerm::covered_state FVTerm::isCovered ( int x, int y //---------------------------------------------------------------------- void FVTerm::updateVTerm() { - // Update data on VTerm + // Updates the character data from all areas to VTerm if ( vdesktop && vdesktop->has_changes ) { @@ -1667,7 +1690,7 @@ void FVTerm::updateVTerm (term_area* area) || ch.code == fc::FullBlock ) 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)); } else if ( ac->transparent ) // transparent @@ -1675,7 +1698,7 @@ void FVTerm::updateVTerm (term_area* area) // restore one character on vterm char_data ch; 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)); } else // not transparent @@ -1698,7 +1721,7 @@ void FVTerm::updateVTerm (term_area* area) || ch.code == fc::FullBlock ) 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)); } else if ( ac->inherit_bg ) @@ -1708,12 +1731,12 @@ void FVTerm::updateVTerm (term_area* area) std::memcpy (&ch, ac, sizeof(char_data)); cc = getCoveredCharacter (gx+1 - ol, gy+1, area->widget); 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)); } else // default { - if ( ! tc->restored && *tc == *ac ) + if ( tc->printed && *tc == *ac ) { std::memcpy (tc, ac, sizeof(char_data)); tc->no_changes = true; @@ -1731,7 +1754,6 @@ void FVTerm::updateVTerm (term_area* area) else if ( ! modified ) line_xmin++; // don't update covered character - tc->restored = false; } _xmin = ax + line_xmin - ol; @@ -2204,8 +2226,23 @@ void FVTerm::clearArea (term_area* area, int fillchar) if ( area == vdesktop ) { - std::fill_n (vterm->text, area_size, nc); - clearTerm (fillchar); + if ( 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; } } @@ -2217,10 +2254,13 @@ void FVTerm::clearArea (term_area* area, int fillchar) for (int y=0; y < area->height; y++) { int pos = y * total_width; + // area std::fill_n (&area->text[pos], total_width, nc); + // right shadow std::fill_n (&area->text[pos+area->width], area->right_shadow, t_char); } + // bottom shadow for (int y=0; y < area->bottom_shadow; y++) { 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++) { - area->changes[i].xmin = 0; area->changes[i].xmax = w - 1; @@ -2486,7 +2525,7 @@ void FVTerm::init() term_attribute.trans_shadow = \ term_attribute.inherit_bg = \ term_attribute.no_changes = \ - term_attribute.restored = false; + term_attribute.printed = false; // next_attribute contains the state of the next printed character std::memcpy (&next_attribute, &term_attribute, sizeof(char_data)); @@ -2529,3 +2568,20 @@ void FVTerm::finish() if ( 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; +} diff --git a/src/fvterm.h b/src/fvterm.h index c422d15f..bbdd26d6 100644 --- a/src/fvterm.h +++ b/src/fvterm.h @@ -94,7 +94,7 @@ class FVTerm : public FObject, public FTerm // Mutators static void setTermXY (register int, register int); - static void clearTerm (int = ' '); + static bool clearTerm (int = ' '); static bool hideCursor (bool); static bool hideCursor(); static bool showCursor(); @@ -330,6 +330,8 @@ class FVTerm : public FObject, public FTerm // Methods void init(); void finish(); + static void markAsPrinted (uInt, uInt); + static void markAsPrinted (uInt, uInt, uInt); // Data Members static std::queue* output_buffer;