diff --git a/doc/TODO b/doc/TODO index f2ed0d68..d737c6e4 100644 --- a/doc/TODO +++ b/doc/TODO @@ -4,9 +4,6 @@ Bugs Improvements ~~~~~~~~~~~~ -- If t_exit_underline_mode == "\E[24m" - -> implement t_exit_bold_mode with "\E[21m" - -> implement t_exit_reverse_mode with "\E[27m" - New behavior in FTerm::appendAttributes(...) - 1st: reset don't needed attributes (bold, reverse and underline) use 'sgr' for this, to do this in one step => 3rd is don't need diff --git a/scripts/valgrind.sh b/scripts/valgrind.sh index e6827a25..991cf455 100755 --- a/scripts/valgrind.sh +++ b/scripts/valgrind.sh @@ -1,7 +1,23 @@ #!/bin/bash -# Findet uninitialisiertem Speicher, Pufferüberläufe, Speicherlecks und entdeckt Speicherzugriffe auf freigegebene Bereiche +# Finds uninitialized memory, buffer overflows, memory leaks and discovered access to deallocated memory + +if [ -z "$1" ] +then + PROG="../test/.libs/ui" +else + PROG="$1" +fi + +# Is the file executable? +test ! -x "$PROG" && echo "No executable file not found" && exit -1 + +# ELF executable file? +ELFMAGIC="$(echo -e "\x7fELF")" +MAGIC="$(dd bs=1 count=4 if="$PROG" 2>/dev/null)" +test "$MAGIC" != "$ELFMAGIC" && echo "No ELF executable file" && exit -2 + +LD_LIBRARY_PATH=../src/.libs/ valgrind --tool=memcheck --suppressions=../doc/ncurses.supp --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes --track-origins=yes --log-file=./valgrind.txt "$PROG" "$@" -LD_LIBRARY_PATH=../src/.libs/ valgrind --tool=memcheck --suppressions=../doc/ncurses.supp --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes --track-origins=yes --log-file=./valgrind.txt ../test/.libs/ui "$@" less ./valgrind.txt rm -f ./valgrind.txt diff --git a/src/ftcap_map.h b/src/ftcap_map.h index 8f29fdd8..1c31aa83 100644 --- a/src/ftcap_map.h +++ b/src/ftcap_map.h @@ -63,13 +63,24 @@ static tcap_map tcap[] = { 0, "te" }, // exit_ca_mode -> strings to end programs using cup { 0, "eA" }, // enable_acs -> enable alternate char set { 0, "md" }, // enter_bold_mode -> turn on bold (extra bright) mode + { 0, "me" }, // exit_bold_mode -> turn off bold mode + { 0, "mh" }, // enter_dim_mode -> turn on half-bright + { 0, "me" }, // exit_dim_mode -> turn off half-bright + { 0, "ZH" }, // enter_italics_mode -> Enter italic mode + { 0, "ZR" }, // exit_italics_mode -> End italic mode { 0, "mb" }, // enter_blink_mode -> turn on blinking + { 0, "me" }, // exit_blink_mode -> turn off blinking { 0, "us" }, // enter_underline_mode -> begin underline mode { 0, "ue" }, // exit_underline_mode -> exit underline mode { 0, "mr" }, // enter_reverse_mode -> turn on reverse video mode + { 0, "me" }, // exit_reverse_mode -> turn off reverse video mode + { 0, "mk" }, // enter_secure_mode -> turn on blank mode (characters invisible) + { 0, "me" }, // exit_secure_mode -> turn off blank mode (characters visible) + { 0, "XX" }, // enter_crossed_out_mode -> turn on mark character as deleted + { 0, "me" }, // exit_crossed_out_mode -> turn off mark character as deleted { 0, "so" }, // enter_standout_mode -> begin standout mode - { 0, "me" }, // exit_attribute_mode -> turn off all attributes { 0, "se" }, // exit_standout_mode -> exit standout mode + { 0, "me" }, // exit_attribute_mode -> turn off all attributes { 0, "as" }, // enter_alt_charset_mode -> start alternate character set (P) { 0, "ae" }, // exit_alt_charset_mode -> end alternate character set (P) { 0, "S2" }, // enter_pc_charset_mode -> Enter PC character display mode @@ -136,13 +147,24 @@ enum termcaps t_exit_ca_mode, t_enable_acs, t_enter_bold_mode, + t_exit_bold_mode, + t_enter_dim_mode, + t_exit_dim_mode, + t_enter_italics_mode, + t_exit_italics_mode, t_enter_blink_mode, + t_exit_blink_mode, t_enter_underline_mode, t_exit_underline_mode, t_enter_reverse_mode, + t_exit_reverse_mode, + t_enter_secure_mode, + t_exit_secure_mode, + t_enter_crossed_out_mode, + t_exit_crossed_out_mode, t_enter_standout_mode, - t_exit_attribute_mode, t_exit_standout_mode, + t_exit_attribute_mode, t_enter_alt_charset_mode, t_exit_alt_charset_mode, t_enter_pc_charset_mode, diff --git a/src/fterm.cpp b/src/fterm.cpp index 4512453a..ef9a9f4e 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -38,9 +38,13 @@ uInt FTerm::baudrate; uInt FTerm::tabstop; bool FTerm::resize_term; bool FTerm::bold; +bool FTerm::dim; +bool FTerm::italic; bool FTerm::reverse; bool FTerm::underline; bool FTerm::term_bold; +bool FTerm::term_dim; +bool FTerm::term_italic; bool FTerm::term_reverse; bool FTerm::term_underline; bool FTerm::hiddenCursor; @@ -1133,6 +1137,34 @@ void FTerm::init_termcaps() exit_underline_caused_reset = true; else exit_underline_caused_reset = false; + + // test for standard ECMA-48 terminal + if ( strncmp(tcap[t_exit_underline_mode].string, "\033[24m", 5) == 0 ) + { + tcap[t_exit_bold_mode].string = \ + const_cast("\033[22m"); // Exit dim, too + + tcap[t_exit_dim_mode].string = \ + const_cast("\033[22m"); + + tcap[t_exit_underline_mode].string = \ + const_cast("\033[24m"); + + tcap[t_exit_blink_mode].string = \ + const_cast("\033[25m"); + + tcap[t_exit_reverse_mode].string = \ + const_cast("\033[27m"); + + tcap[t_exit_secure_mode].string = \ + const_cast("\033[28m"); + + tcap[t_enter_crossed_out_mode].string = \ + const_cast("\033[9m"); + + tcap[t_exit_crossed_out_mode].string = \ + const_cast("\033[29m"); + } } // read termcap key strings @@ -1316,9 +1348,13 @@ void FTerm::init() hiddenCursor = \ mouse_support = \ bold = \ + dim = \ + italic = \ underline = \ reverse = \ term_bold = \ + term_dim = \ + term_italic = \ term_underline = \ term_reverse = \ force_vt100 = \ @@ -1520,7 +1556,7 @@ void FTerm::init() // mintty can't reset these settings setXTermBackground("rgb:8080/a4a4/ecec"); setXTermForeground("rgb:0000/0000/0000"); - setXTermHighlightBackground("rgb:4a4a/9090/d9d9"); + setXTermHighlightBackground("rgb:8686/8686/8686"); } setRawMode(); @@ -1843,6 +1879,8 @@ void FTerm::resizeArea (term_area* area) default_char.fg_color = fc::Black; default_char.bg_color = fc::Black; default_char.bold = 0; + default_char.dim = 0; + default_char.italic = 0; default_char.reverse = 0; default_char.underline = 0; std::fill_n (area->text, area_size, default_char); @@ -2581,6 +2619,8 @@ void FTerm::resizeVTerm() default_char.fg_color = fc::LightGray; default_char.bg_color = fc::Black; default_char.bold = 0; + default_char.dim = 0; + default_char.italic = 0; default_char.reverse = 0; default_char.underline = 0; std::fill_n (vterm->text, vterm_size, default_char); @@ -3286,6 +3326,82 @@ bool FTerm::setTermBold (bool on) return term_bold; } +//---------------------------------------------------------------------- +bool FTerm::setTermDim (bool on) +{ + if ( on == term_dim ) + return term_dim; + + if ( on ) + { + char* mh = tcap[t_enter_dim_mode].string; + if ( mh ) + appendOutputBuffer (mh); + term_dim = true; + } + else + { + char* me = tcap[t_exit_attribute_mode].string; + if ( me ) + { + char* se = tcap[t_exit_standout_mode].string; + char* ue = tcap[t_exit_underline_mode].string; + char* us = tcap[t_enter_underline_mode].string; + char* mr = tcap[t_enter_reverse_mode].string; + char* md = tcap[t_enter_bold_mode].string; + + // "t_exit_attribute_mode" will reset all attributes! + appendOutputBuffer (me); + + // last color restore + if ( ! monochron ) + { + fg_color = fg_term_color; + bg_color = bg_term_color; + fg_term_color = -1; + bg_term_color = -1; + setTermColor (fg_color, bg_color); + } + // underline mode restore + if ( term_underline && ue && us ) + appendOutputBuffer (us); + // reverse mode restore + if ( term_reverse && me && mr ) + appendOutputBuffer (mr); + // bold mode restore + if ( term_bold && md && se ) + appendOutputBuffer (md); + } + term_dim = false; + } + return term_dim; +} + +//---------------------------------------------------------------------- +bool FTerm::setTermItalic (bool on) +{ + if ( on == term_italic ) + return term_italic; + + if ( on ) + { + char* ZH = tcap[t_enter_italics_mode].string; + if ( ZH ) + appendOutputBuffer (ZH); + term_italic = true; + } + else + { + char* ZR = tcap[t_exit_italics_mode].string; + + if ( ZR ) + appendOutputBuffer (ZR); + + term_italic = false; + } + return term_italic; +} + //---------------------------------------------------------------------- bool FTerm::setTermReverse (bool on) { @@ -3889,6 +4005,8 @@ int FTerm::print (FTerm::term_area* area, FString& s) nc.fg_color = uChar(fg_color); nc.bg_color = uChar(bg_color); nc.bold = bold; + nc.dim = dim; + nc.italic = italic; nc.reverse = reverse; nc.underline = underline; @@ -3901,14 +4019,29 @@ int FTerm::print (FTerm::term_area* area, FString& s) && ay < area->height + area->bottom_shadow ) { char_data* ac; // area character + uChar ac_attr, nc_attr; + uInt ac_color, nc_color; int line_len = area->width + area->right_shadow; ac = &area->text[ay * line_len + ax]; + ac_color = ac->fg_color | ac->bg_color << 8; + nc_color = nc.fg_color | nc.bg_color << 8; + + ac_attr = ac->bold + | ac->reverse << 1 + | ac->dim << 2 + | ac->italic << 3 + | ac->underline << 4; + + nc_attr = nc.bold + | nc.reverse << 1 + | nc.dim << 2 + | nc.italic << 3 + | nc.underline << 4; + if ( (ac->code != nc.code) - || (ac->fg_color | ac->bg_color << 8) - != (nc.fg_color | nc.bg_color << 8) - || (ac->bold | ac->reverse << 1 | ac->underline << 2) - != (nc.bold | nc.reverse << 1 | nc.underline << 2) ) + || ac_color!= nc_color + || ac_attr != nc_attr ) { memcpy (ac, &nc, sizeof(nc)); @@ -3976,6 +4109,8 @@ int FTerm::print (FTerm::term_area* area, register int c) nc.fg_color = uChar(fg_color); nc.bg_color = uChar(bg_color); nc.bold = bold; + nc.dim = dim; + nc.italic = italic; nc.reverse = reverse; nc.underline = underline; @@ -3994,14 +4129,30 @@ int FTerm::print (FTerm::term_area* area, register int c) && ay < area->height + area->bottom_shadow ) { char_data* ac; // area character + uChar ac_attr, nc_attr; + uInt ac_color, nc_color; + int line_len = area->width + area->right_shadow; ac = &area->text[ay * line_len + ax]; + ac_color = ac->fg_color | ac->bg_color << 8; + nc_color = nc.fg_color | nc.bg_color << 8; + + ac_attr = ac->bold + | ac->reverse << 1 + | ac->dim << 2 + | ac->italic << 3 + | ac->underline << 4; + + nc_attr = nc.bold + | nc.reverse << 1 + | nc.dim << 2 + | nc.italic << 3 + | nc.underline << 4; + if ( (ac->code != nc.code) - || (ac->fg_color | ac->bg_color << 8) - != (nc.fg_color | nc.bg_color << 8) - || (ac->bold | ac->reverse << 1 | ac->underline << 2) - != (nc.bold | nc.reverse << 1 | nc.underline << 2) ) + || ac_color != nc_color + || ac_attr != nc_attr ) { memcpy (ac, &nc, sizeof(nc)); @@ -4044,13 +4195,24 @@ void FTerm::appendAttributes (char_data*& screen_attr) { if ( screen_attr->fg_color != fg_term_color || screen_attr->bg_color != bg_term_color ) - setTermColor (screen_attr->fg_color, screen_attr->bg_color); + setTermColor ( screen_attr->fg_color, + screen_attr->bg_color ); + if ( bool(screen_attr->bold) != term_bold ) setTermBold (bool(screen_attr->bold)); + + if ( bool(screen_attr->dim) != term_dim ) + setTermDim (bool(screen_attr->dim)); + + if ( bool(screen_attr->italic) != term_italic ) + setTermItalic (bool(screen_attr->italic)); + if ( bool(screen_attr->reverse) != term_reverse ) setTermReverse (bool(screen_attr->reverse)); + if ( bool(screen_attr->underline) != term_underline ) setTermUnderline (bool(screen_attr->underline)); + if ( isNewFont() ) { switch ( screen_attr->code ) diff --git a/src/fterm.h b/src/fterm.h index 067d3775..0ba606fe 100644 --- a/src/fterm.h +++ b/src/fterm.h @@ -91,6 +91,8 @@ class FTerm static std::map * encoding_set; static bool term_bold; + static bool term_dim; + static bool term_italic; static bool term_reverse; static bool term_underline; static bool hiddenCursor; @@ -182,6 +184,8 @@ class FTerm protected: static bool bold; + static bool dim; + static bool italic; static bool reverse; static bool underline; static bool NewFont; @@ -202,9 +206,11 @@ class FTerm uChar fg_color; // foreground color uChar bg_color; // background color uChar bold : 1; // bold + uChar dim : 1; // dim + uChar italic : 1; // italic uChar reverse : 1; // reverse uChar underline : 1; // underline - uChar : 5; // padding bits + uChar : 3; // padding bits } char_data; typedef struct @@ -334,6 +340,8 @@ class FTerm static int vga2ansi (int); void setColor (int, int); static void setTermColor (int, int); + static int getTermForegroundColor(); + static int getTermBackgroundColor(); static int getMaxColor(); static void xtermMouse (bool); static void enableXTermMouse(); @@ -351,6 +359,8 @@ class FTerm static void beep(); static bool setTermBold (bool); + static bool setTermDim (bool); + static bool setTermItalic (bool); static bool setTermReverse (bool); static bool setTermUnderline (bool); @@ -542,6 +552,14 @@ inline bool FTerm::setCursorOptimisation (bool on) inline bool FTerm::isRaw() { return raw_mode; } +//---------------------------------------------------------------------- +inline int FTerm::getTermForegroundColor() +{ return fg_color; } + +//---------------------------------------------------------------------- +inline int FTerm::getTermBackgroundColor() +{ return bg_color; } + //---------------------------------------------------------------------- inline int FTerm::getMaxColor() { return max_color; } diff --git a/src/fwidget.h b/src/fwidget.h index 1156f6c4..4e8b64e6 100644 --- a/src/fwidget.h +++ b/src/fwidget.h @@ -448,17 +448,27 @@ class FWidget : public FObject, public FTerm static void gotoxy (register int, register int); void clrscr(); - static bool setBold(register bool); + static bool setBold (register bool); static bool setBold(); static bool unsetBold(); static bool isBold(); - static bool setReverse(register bool); + static bool setDim (register bool); + static bool setDim(); + static bool unsetDim(); + static bool isDim(); + + static bool setItalic (register bool); + static bool setItalic(); + static bool unsetItalic(); + static bool isItalic(); + + static bool setReverse (register bool); static bool setReverse(); static bool unsetReverse(); static bool isReverse(); - static bool setUnderline(register bool); + static bool setUnderline (register bool); static bool setUnderline(); static bool unsetUnderline(); static bool isUnderline(); @@ -753,6 +763,38 @@ inline bool FWidget::unsetBold() inline bool FWidget::isBold() { return bold; } +//---------------------------------------------------------------------- +inline bool FWidget::setDim (register bool on) +{ return (dim = on); } + +//---------------------------------------------------------------------- +inline bool FWidget::setDim() +{ return setDim(true); } + +//---------------------------------------------------------------------- +inline bool FWidget::unsetDim() +{ return setDim(false); } + +//---------------------------------------------------------------------- +inline bool FWidget::isDim() +{ return dim; } + +//---------------------------------------------------------------------- +inline bool FWidget::setItalic (register bool on) +{ return (italic = on); } + +//---------------------------------------------------------------------- +inline bool FWidget::setItalic() +{ return setItalic(true); } + +//---------------------------------------------------------------------- +inline bool FWidget::unsetItalic() +{ return setItalic(false); } + +//---------------------------------------------------------------------- +inline bool FWidget::isItalic() +{ return italic; } + //---------------------------------------------------------------------- inline bool FWidget::setReverse (register bool on) { return (reverse = on); } diff --git a/test/menu.cpp b/test/menu.cpp index ee2cbc53..2cc6c907 100644 --- a/test/menu.cpp +++ b/test/menu.cpp @@ -177,13 +177,14 @@ Menu::Menu (FWidget* parent) FLabel* Headline2 = new FLabel(" Function ", this); Headline2->ignorePadding(); - Headline2->setGeometry(15,2,10,1); + Headline2->setGeometry(19,2,10,1); Headline2->setEmphasis(); // Info label - FLabel* Info = new FLabel(" Activate menu bar\n" - "+ Exit", this); - Info->setGeometry(2,1,32,2); + FLabel* Info = new FLabel(" Activate menu bar\n" + "+ Activate menu bar\n" + "+ Exit", this); + Info->setGeometry(2,1,36,3); } //---------------------------------------------------------------------- @@ -278,7 +279,7 @@ int main (int argc, char* argv[]) Menu main_dlg (&app); main_dlg.setText ("Menu example"); - main_dlg.setGeometry (int(1+(app.getWidth()-36)/2), 2, 36, 5); + main_dlg.setGeometry (int(1+(app.getWidth()-40)/2), 2, 40, 6); main_dlg.setShadow(); app.setMainWidget (&main_dlg); diff --git a/test/ui.cpp b/test/ui.cpp index da2c8452..9fc27894 100644 --- a/test/ui.cpp +++ b/test/ui.cpp @@ -33,7 +33,7 @@ class ProgressDialog : public FDialog public: explicit ProgressDialog (FWidget* = 0); // constructor - ~ProgressDialog(); // destructor + ~ProgressDialog(); // destructor }; #pragma pack(pop)