diff --git a/ChangeLog b/ChangeLog index 462ca5fc..3a56b75f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2017-04-08 Markus Gans + * Improved Linux terminal quirks + * Improvement in class FOptiAttr + 2017-04-02 Markus Gans * Improved cygwin terminal quirks * Optimized character set switching in FOptiAttr diff --git a/include/final/foptiattr.h b/include/final/foptiattr.h index faca1c13..39a3b314 100644 --- a/include/final/foptiattr.h +++ b/include/final/foptiattr.h @@ -290,7 +290,6 @@ class FOptiAttr bool switchOn(); bool switchOff(); bool append_sequence (char[]); - bool replace_sequence (char[]); // Data Members capability F_enter_bold_mode; diff --git a/src/foptiattr.cpp b/src/foptiattr.cpp index 0a84b266..15969052 100644 --- a/src/foptiattr.cpp +++ b/src/foptiattr.cpp @@ -566,7 +566,8 @@ char* FOptiAttr::changeAttribute (char_data*& term, char_data*& next) { deactivateAttributes (term, next); } - else if ( F_set_attributes.cap && ! term->attr.bit.pc_charset ) + else if ( F_set_attributes.cap + && ( ! term->attr.bit.pc_charset || alt_equal_pc_charset) ) { changeAttributeSGR (term, next); } @@ -985,7 +986,7 @@ inline bool FOptiAttr::unsetTermAttributes (char_data*& term) reset(term); - if ( replace_sequence(F_exit_attribute_mode.cap) ) + if ( append_sequence(F_exit_attribute_mode.cap) ) return true; else return false; @@ -1340,6 +1341,9 @@ inline void FOptiAttr::deactivateAttributes ( char_data*& term { if ( F_exit_attribute_mode.cap ) { + if ( off.attr.bit.alt_charset ) // Required for rxvt terminals + unsetTermAltCharset(term); + unsetTermAttributes(term); if ( off.attr.bit.pc_charset ) @@ -1373,8 +1377,8 @@ inline void FOptiAttr::changeAttributeSGR ( char_data*& term if ( alt_equal_pc_charset && next->attr.bit.alt_charset ) { - term->attr.bit.pc_charset = true; - off.attr.bit.pc_charset = false; + term->attr.bit.pc_charset = next->attr.bit.pc_charset; + off.attr.bit.pc_charset = false; pc_charset_usable = false; } @@ -1569,10 +1573,12 @@ bool FOptiAttr::caused_reset_attributes (char cap[], uChar test) if ( (test & test_adm3_reset) && std::strncmp (cap, ESC "G0", 3) == 0 ) return true; - if ( (test & same_like_ue) && ue && std::strcmp (cap, ue) == 0 ) + if ( (test & same_like_ue) && ue && std::strcmp (cap, ue) == 0 + && std::strncmp (cap, CSI "24m", 5) != 0) return true; - if ( (test & same_like_se) && se && std::strcmp (cap, se) == 0 ) + if ( (test & same_like_se) && se && std::strcmp (cap, se) == 0 + && std::strncmp (cap, CSI "27m", 5) != 0 ) return true; if ( (test & same_like_me) && me && std::strcmp (cap, me) == 0 ) @@ -1668,15 +1674,3 @@ inline bool FOptiAttr::append_sequence (char seq[]) else return false; } - -//---------------------------------------------------------------------- -inline bool FOptiAttr::replace_sequence (char seq[]) -{ - if ( seq ) - { - std::strncpy (attr_ptr, seq, sizeof(attr_buf) - 1); - return true; - } - else - return false; -} diff --git a/src/fterm.cpp b/src/fterm.cpp index c00a03ee..a093273b 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -3663,6 +3663,9 @@ void FTerm::init_termcaps_linux_quirks() TCAP(fc::t_orig_pair) = \ C_STR(CSI "39;49;25m"); + TCAP(fc::t_exit_reverse_mode) = \ + C_STR(CSI "27m"); + // Avoid underline and dim mode TCAP(fc::t_enter_dim_mode) = 0; TCAP(fc::t_exit_dim_mode) = 0; diff --git a/src/test/foptiattr-test.cpp b/src/test/foptiattr-test.cpp index c3468da6..590d89ee 100644 --- a/src/test/foptiattr-test.cpp +++ b/src/test/foptiattr-test.cpp @@ -72,6 +72,8 @@ class FOptiAttrTest : public CPPUNIT_NS::TestFixture void vga2ansi(); void ansiTest(); void vt100Test(); + void xtermTest(); + void rxvtTest(); private: std::string printSequence (char*); @@ -85,6 +87,8 @@ class FOptiAttrTest : public CPPUNIT_NS::TestFixture CPPUNIT_TEST (vga2ansi); CPPUNIT_TEST (ansiTest); CPPUNIT_TEST (vt100Test); + CPPUNIT_TEST (xtermTest); + CPPUNIT_TEST (rxvtTest); // End of test suite definition CPPUNIT_TEST_SUITE_END(); @@ -148,6 +152,8 @@ void FOptiAttrTest::vga2ansi() //---------------------------------------------------------------------- void FOptiAttrTest::ansiTest() { + // Simulate an ansi terminal + FOptiAttr oa; oa.setDefaultColorSupport(); // ANSI default color //oa.setCygwinTerminal(); // Cygwin bold color fix @@ -436,8 +442,6 @@ void FOptiAttrTest::ansiTest() CPPUNIT_ASSERT ( *from != *to ); CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) , C_STR(CSI "0;10;11m") ); - CPPUNIT_ASSERT ( *from != *to ); - CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to), C_STR("") ); CPPUNIT_ASSERT ( *from == *to ); CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); @@ -445,7 +449,7 @@ void FOptiAttrTest::ansiTest() to->attr.bit.alt_charset = false; CPPUNIT_ASSERT ( *from != *to ); CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) - , C_STR(CSI "0m") ); + , C_STR(CSI "10m" CSI "0m") ); CPPUNIT_ASSERT ( *from == *to ); CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); @@ -499,8 +503,7 @@ void FOptiAttrTest::ansiTest() to->attr.bit.bold = false; CPPUNIT_ASSERT ( *from != *to ); CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) - , C_STR(CSI "0m" CSI "36m" CSI "44m" CSI "11m" - CSI "5m" CSI "7m" CSI "8m") ); + , C_STR(CSI "0;10;7;5;8;11m" CSI "36m" CSI "44m") ); CPPUNIT_ASSERT ( *from == *to ); CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); @@ -508,15 +511,16 @@ void FOptiAttrTest::ansiTest() to->attr.bit.dim = false; CPPUNIT_ASSERT ( *from != *to ); CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) - , C_STR(CSI "0m" CSI "36m" CSI "44m" CSI "11m" - CSI "5m" CSI "7m" CSI "8m") ); + , C_STR(CSI "0;10;7;5;8;11m" CSI "36m" CSI "44m") ); CPPUNIT_ASSERT ( *from == *to ); CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); // Italic off to->attr.bit.italic = false; CPPUNIT_ASSERT ( *from != *to ); - CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to), C_STR("") ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0;10;7;5;8;11m" + CSI "36m" CSI "44m") ); CPPUNIT_ASSERT ( *from == *to ); CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); @@ -529,8 +533,7 @@ void FOptiAttrTest::ansiTest() to->attr.bit.blink = false; CPPUNIT_ASSERT ( *from != *to ); CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) - , C_STR(CSI "0m" CSI "36m" CSI "44m" - CSI "11m" CSI "7m" CSI "8m") ); + , C_STR(CSI "0;10;7;8;11m" CSI "36m" CSI "44m") ); CPPUNIT_ASSERT ( *from == *to ); CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); @@ -538,8 +541,7 @@ void FOptiAttrTest::ansiTest() to->attr.bit.reverse = false; CPPUNIT_ASSERT ( *from != *to ); CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) - , C_STR(CSI "0m" CSI "36m" CSI "44m" - CSI "11m" CSI "8m") ); + , C_STR(CSI "0;10;8;11m" CSI "36m" CSI "44m") ); CPPUNIT_ASSERT ( *from == *to ); CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); @@ -552,7 +554,7 @@ void FOptiAttrTest::ansiTest() to->attr.bit.invisible = false; CPPUNIT_ASSERT ( *from != *to ); CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) - , C_STR(CSI "0m" CSI "36m" CSI "44m" CSI "11m") ); + , C_STR(CSI "0;10;11m" CSI "36m" CSI "44m") ); CPPUNIT_ASSERT ( *from == *to ); CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); @@ -560,7 +562,7 @@ void FOptiAttrTest::ansiTest() to->attr.bit.protect = false; CPPUNIT_ASSERT ( *from != *to ); CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) - , C_STR(CSI "0m" CSI "36m" CSI "44m" CSI "11m") ); + , C_STR(CSI "0;10;11m" CSI "36m" CSI "44m") ); CPPUNIT_ASSERT ( *from == *to ); CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); @@ -568,21 +570,23 @@ void FOptiAttrTest::ansiTest() to->attr.bit.crossed_out = false; CPPUNIT_ASSERT ( *from != *to ); CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) - , C_STR(CSI "0m" CSI "36m" CSI "44m" CSI "11m") ); + , C_STR(CSI "0;10;11m" CSI "36m" CSI "44m") ); CPPUNIT_ASSERT ( *from == *to ); CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); // Double underline off to->attr.bit.dbl_underline = false; CPPUNIT_ASSERT ( *from != *to ); - CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to), C_STR("") ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0;10;11m" CSI "36m" CSI "44m") ); CPPUNIT_ASSERT ( *from == *to ); CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); // Alternate character set off to->attr.bit.alt_charset = false; CPPUNIT_ASSERT ( *from != *to ); - CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to), C_STR("") ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0;10m" CSI "11m" CSI "36m" CSI "44m") ); CPPUNIT_ASSERT ( *from == *to ); CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); @@ -616,6 +620,8 @@ void FOptiAttrTest::ansiTest() //---------------------------------------------------------------------- void FOptiAttrTest::vt100Test() { + // Simulate a vt100 terminal + FOptiAttr oa; //oa.setDefaultColorSupport(); // ANSI default color //oa.setCygwinTerminal(); // Cygwin bold color fix @@ -903,7 +909,7 @@ void FOptiAttrTest::vt100Test() to->attr.bit.alt_charset = false; CPPUNIT_ASSERT ( *from != *to ); CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) - , C_STR(CSI "0m$<2>") ); + , C_STR("\017" CSI "0m$<2>") ); CPPUNIT_ASSERT ( *from == *to ); CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); @@ -1087,6 +1093,961 @@ void FOptiAttrTest::vt100Test() delete from; } +//---------------------------------------------------------------------- +void FOptiAttrTest::xtermTest() +{ + // Simulate an xterm-256color terminal + + FOptiAttr oa; + oa.setDefaultColorSupport(); // ANSI default color +//oa.setCygwinTerminal(); // Cygwin bold color fix + oa.setNoColorVideo (0); + oa.setMaxColor (256); + oa.set_enter_bold_mode (C_STR(CSI "1m")); + oa.set_exit_bold_mode (C_STR(CSI "22m")); + oa.set_enter_dim_mode (C_STR(CSI "2m")); + oa.set_exit_dim_mode (C_STR(CSI "22m")); + oa.set_enter_italics_mode (C_STR(CSI "3m")); + oa.set_exit_italics_mode (C_STR(CSI "23m")); + oa.set_enter_underline_mode (C_STR(CSI "4m")); + oa.set_exit_underline_mode (C_STR(CSI "24m")); + oa.set_enter_blink_mode (C_STR(CSI "5m")); + oa.set_exit_blink_mode (C_STR(CSI "25m")); + oa.set_enter_reverse_mode (C_STR(CSI "7m")); + oa.set_exit_reverse_mode (C_STR(CSI "27m")); + oa.set_enter_standout_mode (C_STR(CSI "7m")); + oa.set_exit_standout_mode (C_STR(CSI "27m")); + oa.set_enter_secure_mode (C_STR(CSI "8m")); + oa.set_exit_secure_mode (C_STR(CSI "28m")); + oa.set_enter_protected_mode (0); + oa.set_exit_protected_mode (C_STR(CSI "0m")); + oa.set_enter_crossed_out_mode (C_STR(CSI "9m")); + oa.set_exit_crossed_out_mode (C_STR(CSI "29m")); + oa.set_enter_dbl_underline_mode (C_STR(CSI "21m")); + oa.set_exit_dbl_underline_mode (C_STR(CSI "24m")); + oa.set_set_attributes (C_STR("%?%p9%t" ESC "(0" + "%e" ESC "(B%;" CSI "0" + "%?%p6%t;1%;" + "%?%p5%t;2%;" + "%?%p2%t;4%;" + "%?%p1%p3%|%t;7%;" + "%?%p4%t;5%;" + "%?%p7%t;8%;m")); + oa.set_exit_attribute_mode (C_STR(CSI "0m")); + oa.set_enter_alt_charset_mode (C_STR(ESC "(0")); + oa.set_exit_alt_charset_mode (C_STR(ESC "(B")); + oa.set_enter_pc_charset_mode (0); + oa.set_exit_pc_charset_mode (0); + oa.set_a_foreground_color (C_STR(CSI "%?%p1%{8}%<" + "%t3%p1%d" + "%e%p1%{16}%<" + "%t9%p1%{8}%-%d" + "%e38;5;%p1%d%;m")); + oa.set_a_background_color (C_STR(CSI "%?%p1%{8}%<" + "%t4%p1%d" + "%e%p1%{16}%<" + "%t10%p1%{8}%-%d" + "%e48;5;%p1%d%;m")); + oa.set_foreground_color (0); + oa.set_background_color (0); + oa.set_term_color_pair (0); + oa.set_orig_pair (C_STR(CSI "39;49m")); + oa.set_orig_orig_colors (0); + oa.initialize(); + + FOptiAttr::char_data* from = new FOptiAttr::char_data(); + FOptiAttr::char_data* to = new FOptiAttr::char_data(); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Default color + bold + from->fg_color = fc::Default; + from->bg_color = fc::Default; + to->attr.bit.bold = true; + to->fg_color = fc::Default; + to->bg_color = fc::Default; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(ESC "(B" CSI "0;1m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Blue text on white background + dim + italic + to->fg_color = fc::Blue; + to->bg_color = fc::White; + to->attr.bit.dim = true; + to->attr.bit.italic = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(ESC "(B" CSI "0;1;2m" CSI "3m" + CSI "34m" CSI "107m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Reset attributes + default background + to->attr.bit.bold = false; + to->attr.bit.dim = false; + to->attr.bit.italic = false; + to->bg_color = fc::Default; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m" CSI "34m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Red text on black background + to->fg_color = fc::Red; + to->bg_color = fc::Black; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "31m" CSI "40m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // 256 color text and background + to->fg_color = fc::SpringGreen3; + to->bg_color = fc::NavyBlue; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "38;5;42m" CSI "48;5;17m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Bold on (with default colors) + to->fg_color = fc::Default; + to->bg_color = fc::Default; + to->attr.bit.bold = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(ESC "(B" CSI "0;1m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Bold off (with default colors) + to->attr.bit.bold = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Dim on (with default colors) + to->attr.bit.dim = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(ESC "(B" CSI "0;2m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Dim off (with default colors) + to->attr.bit.dim = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Italic on (with default colors) + to->attr.bit.italic = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(ESC "(B" CSI "0m" CSI "3m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Italic off (with default colors) + to->attr.bit.italic = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Underline on (with default colors) + to->attr.bit.underline = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(ESC "(B" CSI "0;4m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Underline off (with default colors) + to->attr.bit.underline = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Blink on (with default colors) + to->attr.bit.blink = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(ESC "(B" CSI "0;5m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Blink off (with default colors) + to->attr.bit.blink = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Reverse on (with default colors) + to->attr.bit.reverse = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(ESC "(B" CSI "0;7m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Reverse off (with default colors) + to->attr.bit.reverse = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Standout on (with default colors) + to->attr.bit.standout = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(ESC "(B" CSI "0;7m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Standout off (with default colors) + to->attr.bit.standout = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Invisible on (with default colors) + to->attr.bit.invisible = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(ESC "(B" CSI "0;8m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Invisible off (with default colors) + to->attr.bit.invisible = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Protect on (with default colors) + to->attr.bit.protect = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(ESC "(B" CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Protect off (with default colors) + to->attr.bit.protect = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Crossed out on (with default colors) + to->attr.bit.crossed_out = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(ESC "(B" CSI "0m" CSI "9m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Crossed out off (with default colors) + to->attr.bit.crossed_out = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Double underline on (with default colors) + to->attr.bit.dbl_underline = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(ESC "(B" CSI "0m" CSI "21m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Double underline off (with default colors) + to->attr.bit.dbl_underline = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Alternate character set on (with default colors) + to->attr.bit.alt_charset = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(ESC "(0" CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Alternate character set off (with default colors) + to->attr.bit.alt_charset = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(ESC "(B" CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // PC character set on (with default colors) + to->attr.bit.pc_charset = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(ESC "(B" CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // PC character set off (with default colors) + to->attr.bit.pc_charset = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Turn on all attributes (with default colors) + to->attr.bit.pc_charset = true; + to->attr.bit.bold = true; + to->attr.bit.dim = true; + to->attr.bit.italic = true; + to->attr.bit.underline = true; + to->attr.bit.blink = true; + to->attr.bit.reverse = true; + to->attr.bit.standout = true; + to->attr.bit.invisible = true; + to->attr.bit.protect = true; + to->attr.bit.crossed_out = true; + to->attr.bit.dbl_underline = true; + to->attr.bit.alt_charset = true; + to->attr.bit.pc_charset = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(ESC "(0" CSI "0;1;2;4;7;5;8m" CSI "3m" + CSI "9m" CSI "21m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Cyan text on blue background + to->fg_color = fc::Cyan; + to->bg_color = fc::Blue; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "36m" CSI "44m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Bold off + to->attr.bit.bold = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "22m" CSI "2m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Dim off + to->attr.bit.dim = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "22m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Italic off + to->attr.bit.italic = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "23m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Underline off + to->attr.bit.underline = false; + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "24m" CSI "21m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + + // Blink off + to->attr.bit.blink = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "25m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Reverse off + to->attr.bit.reverse = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "27m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Standout off + to->attr.bit.standout = false; + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "27m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Invisible off + to->attr.bit.invisible = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "28m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Protect off + to->attr.bit.protect = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m" CSI "36m" CSI "44m" ESC "(0" CSI "9m" CSI "21m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Crossed out off + to->attr.bit.crossed_out = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "29m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Double underline off + to->attr.bit.dbl_underline = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "24m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Alternate character set off + to->attr.bit.alt_charset = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(ESC "(B") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // PC character set off + to->attr.bit.pc_charset = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m" CSI "36m" CSI "44m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Green text color + to->fg_color = fc::Green; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to), C_STR(CSI "32m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Default text color + to->fg_color = fc::Default; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( printSequence(oa.changeAttribute(from, to)).c_str() + , C_STR("Esc [ 3 9 m ") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + delete to; + delete from; +} + +//---------------------------------------------------------------------- +void FOptiAttrTest::rxvtTest() +{ + // Simulate an rxvt terminal + + FOptiAttr oa; + oa.setDefaultColorSupport(); // ANSI default color +//oa.setCygwinTerminal(); // Cygwin bold color fix + oa.setNoColorVideo (0); + oa.setMaxColor (8); + oa.set_enter_bold_mode (C_STR(CSI "1m")); + oa.set_exit_bold_mode (C_STR(CSI "22m")); + oa.set_enter_dim_mode (0); + oa.set_exit_dim_mode (C_STR(CSI "22m")); + oa.set_enter_italics_mode (0); + oa.set_exit_italics_mode (0); + oa.set_enter_underline_mode (C_STR(CSI "4m")); + oa.set_exit_underline_mode (C_STR(CSI "24m")); + oa.set_enter_blink_mode (C_STR(CSI "5m")); + oa.set_exit_blink_mode (C_STR(CSI "25m")); + oa.set_enter_reverse_mode (C_STR(CSI "7m")); + oa.set_exit_reverse_mode (C_STR(CSI "27m")); + oa.set_enter_standout_mode (C_STR(CSI "7m")); + oa.set_exit_standout_mode (C_STR(CSI "27m")); + oa.set_enter_secure_mode (0); + oa.set_exit_secure_mode (C_STR(CSI "28m")); + oa.set_enter_protected_mode (0); + oa.set_exit_protected_mode (C_STR(CSI "0m")); + oa.set_enter_crossed_out_mode (C_STR(CSI "9m")); + oa.set_exit_crossed_out_mode (C_STR(CSI "29m")); + oa.set_enter_dbl_underline_mode (C_STR(CSI "21m")); + oa.set_exit_dbl_underline_mode (C_STR(CSI "24m")); + oa.set_set_attributes (C_STR(CSI "0" + "%?%p6%t;1%;" + "%?%p2%t;4%;" + "%?%p1%p3%|%t;7%;" + "%?%p4%t;5%;m" + "%?%p9%t\016%e\017%;")); + oa.set_exit_attribute_mode (C_STR(CSI "0m")); + oa.set_enter_alt_charset_mode (C_STR("\016")); + oa.set_exit_alt_charset_mode (C_STR("\017")); + oa.set_enter_pc_charset_mode (0); + oa.set_exit_pc_charset_mode (0); + oa.set_a_foreground_color (C_STR(CSI "3%p1%dm")); + oa.set_a_background_color (C_STR(CSI "4%p1%dm")); + oa.set_foreground_color (0); + oa.set_background_color (0); + oa.set_term_color_pair (0); + oa.set_orig_pair (C_STR(CSI "39;49m")); + oa.set_orig_orig_colors (0); + oa.initialize(); + + FOptiAttr::char_data* from = new FOptiAttr::char_data(); + FOptiAttr::char_data* to = new FOptiAttr::char_data(); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Default color + bold + from->fg_color = fc::Default; + from->bg_color = fc::Default; + to->attr.bit.bold = true; + to->fg_color = fc::Default; + to->bg_color = fc::Default; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0;1m\017") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Blue text on white background + dim + italic + to->fg_color = fc::Blue; + to->bg_color = fc::White; + to->attr.bit.dim = true; + to->attr.bit.italic = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0;1m\017" CSI "34m" CSI "47m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Reset attributes + default background + to->attr.bit.bold = false; + to->attr.bit.dim = false; + to->attr.bit.italic = false; + to->bg_color = fc::Default; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m" CSI "34m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Red text on black background + to->fg_color = fc::Red; + to->bg_color = fc::Black; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "31m" CSI "40m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // 256 color text and background + to->fg_color = fc::SpringGreen3; + to->bg_color = fc::NavyBlue; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "32m" CSI "44m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Bold on (with default colors) + to->fg_color = fc::Default; + to->bg_color = fc::Default; + to->attr.bit.bold = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0;1m\017") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Bold off (with default colors) + to->attr.bit.bold = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Dim on (with default colors) + to->attr.bit.dim = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m\017") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Dim off (with default colors) + to->attr.bit.dim = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Italic on (with default colors) + to->attr.bit.italic = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m\017") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Italic off (with default colors) + to->attr.bit.italic = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Underline on (with default colors) + to->attr.bit.underline = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0;4m\017") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Underline off (with default colors) + to->attr.bit.underline = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Blink on (with default colors) + to->attr.bit.blink = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0;5m\017") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Blink off (with default colors) + to->attr.bit.blink = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Reverse on (with default colors) + to->attr.bit.reverse = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0;7m\017") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Reverse off (with default colors) + to->attr.bit.reverse = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Standout on (with default colors) + to->attr.bit.standout = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0;7m\017") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Standout off (with default colors) + to->attr.bit.standout = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Invisible on (with default colors) + to->attr.bit.invisible = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m\017") ); + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT ( to->code == ' ' ); + from->code = ' '; + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Invisible off (with default colors) + to->attr.bit.invisible = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Protect on (with default colors) + to->attr.bit.protect = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m\017") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Protect off (with default colors) + to->attr.bit.protect = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Crossed out on (with default colors) + to->attr.bit.crossed_out = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m\017" CSI "9m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Crossed out off (with default colors) + to->attr.bit.crossed_out = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Double underline on (with default colors) + to->attr.bit.dbl_underline = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m\017" CSI "21m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Double underline off (with default colors) + to->attr.bit.dbl_underline = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Alternate character set on (with default colors) + to->attr.bit.alt_charset = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m\016") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Alternate character set off (with default colors) + to->attr.bit.alt_charset = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR("\017" CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // PC character set on (with default colors) + to->attr.bit.pc_charset = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m\017") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // PC character set off (with default colors) + to->attr.bit.pc_charset = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Turn on all attributes (with default colors) + to->attr.bit.pc_charset = true; + to->attr.bit.bold = true; + to->attr.bit.dim = true; + to->attr.bit.italic = true; + to->attr.bit.underline = true; + to->attr.bit.blink = true; + to->attr.bit.reverse = true; + to->attr.bit.standout = true; + to->attr.bit.invisible = true; + to->attr.bit.protect = true; + to->attr.bit.crossed_out = true; + to->attr.bit.dbl_underline = true; + to->attr.bit.alt_charset = true; + to->attr.bit.pc_charset = true; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0;1;4;7;5m\016" + CSI "9m" CSI "21m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Cyan text on blue background + to->fg_color = fc::Cyan; + to->bg_color = fc::Blue; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "36m" CSI "44m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Bold off + to->attr.bit.bold = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "22m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Dim off + to->attr.bit.dim = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "22m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Italic off + to->attr.bit.italic = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR("") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Underline off + to->attr.bit.underline = false; + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "24m" CSI "21m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + + // Blink off + to->attr.bit.blink = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "25m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Reverse off + to->attr.bit.reverse = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "27m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Standout off + to->attr.bit.standout = false; + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "27m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Invisible off + to->attr.bit.invisible = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "28m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Protect off + to->attr.bit.protect = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m" CSI "36m" CSI "44m\016" CSI "9m" CSI "21m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Crossed out off + to->attr.bit.crossed_out = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "29m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Double underline off + to->attr.bit.dbl_underline = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "24m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Alternate character set off + to->attr.bit.alt_charset = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR("\017") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // PC character set off + to->attr.bit.pc_charset = false; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to) + , C_STR(CSI "0m" CSI "36m" CSI "44m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Green text color + to->fg_color = fc::Green; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to), C_STR(CSI "32m") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + // Default text color + to->fg_color = fc::Default; + CPPUNIT_ASSERT ( *from != *to ); + CPPUNIT_ASSERT_CSTRING ( printSequence(oa.changeAttribute(from, to)).c_str() + , C_STR("Esc [ 3 9 m ") ); + CPPUNIT_ASSERT ( *from == *to ); + CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 ); + + delete to; + delete from; +} + //---------------------------------------------------------------------- std::string FOptiAttrTest::printSequence (char* str) {