diff --git a/ChangeLog b/ChangeLog index 924f442e..a9b7a1b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2021-06-26 Markus Gans + * Global non-constant variables are now encapsulated in classes + 2021-06-19 Markus Gans * Moving the creator methods from FTerm to its own class diff --git a/examples/7segment.cpp b/examples/7segment.cpp index 8d9f5c69..be17a55c 100644 --- a/examples/7segment.cpp +++ b/examples/7segment.cpp @@ -185,7 +185,7 @@ void SegmentView::get7Segment (const wchar_t c) //---------------------------------------------------------------------- void SegmentView::draw() { - std::vector tbuffer{3}; + std::vector tbuffer(3); finalcut::FTermBuffer left_space{}; FDialog::draw(); diff --git a/examples/checklist.cpp b/examples/checklist.cpp index 127fc48d..da56c235 100644 --- a/examples/checklist.cpp +++ b/examples/checklist.cpp @@ -24,7 +24,6 @@ #include #include #include -#include #include diff --git a/examples/term-attributes.cpp b/examples/term-attributes.cpp index 3a252da5..daad5334 100644 --- a/examples/term-attributes.cpp +++ b/examples/term-attributes.cpp @@ -287,7 +287,7 @@ void AttribDemo::printAltCharset() if ( ! finalcut::FTerm::isMonochron() ) setColor (wc->label_fg, wc->label_bg); - print() << FPoint{1, 1} << "alternate charset: "; + print() << FPoint{1, 1} << "Alternate charset: "; if ( parent->getBGColor() == FColor::Default ) { diff --git a/src/fcharmap.cpp b/src/fcharmap.cpp index b8dfede8..5ec240c7 100644 --- a/src/fcharmap.cpp +++ b/src/fcharmap.cpp @@ -3,7 +3,7 @@ * * * This file is part of the FINAL CUT widget toolkit * * * -* Copyright 2015-2020 Markus Gans * +* Copyright 2015-2021 Markus Gans * * * * FINAL CUT is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -29,10 +29,47 @@ namespace finalcut { -namespace fc +//---------------------------------------------------------------------- +auto FCharMap::getInstance() -> FCharMap& { + static const auto& char_map = make_unique(); + return *char_map; +} -std::array character = +//---------------------------------------------------------------------- +wchar_t& FCharMap::getCharacter ( CharEncodeMap& char_enc + , const Encoding& enc ) +{ + const auto array = reinterpret_cast(&char_enc); + return array[std::size_t(enc)]; +} + +//---------------------------------------------------------------------- +FCharMap::CharEncodeType& FCharMap::getCharEncodeMap() +{ + return character; +} + +//---------------------------------------------------------------------- +const FCharMap::DECGraphicsType& FCharMap::getDECSpecialGraphics() +{ + return dec_special_graphics; +} + +//---------------------------------------------------------------------- +const FCharMap::Cp437UcsType& FCharMap::getCP437UCSMap() +{ + return cp437_ucs; +} + +//---------------------------------------------------------------------- +const FCharMap::HalfFullWidthType& FCharMap::getHalfFullWidthMap() +{ + return halfwidth_fullwidth; +} + +//---------------------------------------------------------------------- +FCharMap::CharEncodeType FCharMap::character = {{ // .--------------------- Unicode (UTF-8) // | .--------------- VT100 @@ -161,8 +198,8 @@ std::array character = * (2) Only supported in use with newfont */ - -constexpr std::array dec_special_graphics = +//---------------------------------------------------------------------- +constexpr FCharMap::DECGraphicsType FCharMap::dec_special_graphics = {{ {VT100Key::rarrow , UniChar::BlackRightPointingPointer}, // ► {VT100Key::larrow , UniChar::BlackLeftPointingPointer}, // ◄ @@ -205,7 +242,8 @@ constexpr std::array dec_special_graphics = {VT100Key::diamond , UniChar::Bullet} // ◆ }}; -constexpr std::array, 256> cp437_ucs = +//---------------------------------------------------------------------- +constexpr FCharMap::Cp437UcsType FCharMap::cp437_ucs = {{ {{0x00, 0x0000}}, // null {{0x01, 0x263a}}, // white smiling face @@ -465,8 +503,9 @@ constexpr std::array, 256> cp437_ucs = {{0xff, 0x00a0}} // no-break space }}; +//---------------------------------------------------------------------- // Based on http://www.unicode.org/charts/PDF/UFF00.pdf -constexpr std::array, 227> halfwidth_fullwidth = +constexpr FCharMap::HalfFullWidthType FCharMap::halfwidth_fullwidth = {{ // Fullwidth ASCII variants {{0x0020, 0x3000}}, // ' ' -> ' ' @@ -704,7 +743,4 @@ constexpr std::array, 227> halfwidth_fullwidth = {{0xffee, 0x25cb}} // ○ -> ○ }}; -} // namespace fc - } // namespace finalcut - diff --git a/src/fkey_map.cpp b/src/fkey_map.cpp index 71766c71..8f24fee9 100644 --- a/src/fkey_map.cpp +++ b/src/fkey_map.cpp @@ -3,7 +3,7 @@ * * * This file is part of the FINAL CUT widget toolkit * * * -* Copyright 2018-2020 Markus Gans * +* Copyright 2018-2021 Markus Gans * * * * FINAL CUT is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -28,10 +28,33 @@ namespace finalcut { -namespace fc +//---------------------------------------------------------------------- +auto FKeyMap::getInstance() -> FKeyMap& { + static const auto& key_map = make_unique(); + return *key_map; +} -std::array fkey_cap_table +//---------------------------------------------------------------------- +FKeyMap::KeyCapMapType& FKeyMap::getKeyCapMap() +{ + return fkey_cap_table; +} + +//---------------------------------------------------------------------- +const FKeyMap::KeyMapType& FKeyMap::getKeyMap() +{ + return fkey_table; +} + +//---------------------------------------------------------------------- +const FKeyMap::KeyNameType& FKeyMap::getKeyName() +{ + return fkeyname; +} + +//---------------------------------------------------------------------- +FKeyMap::KeyCapMapType FKeyMap::fkey_cap_table {{ { FKey::Backspace , nullptr, "kb" }, // Backspace key { FKey::Clear_all_tabs , nullptr, "ka" }, // Clear-all-tabs key @@ -228,7 +251,8 @@ std::array fkey_cap_table { FKey::Lower_right , ESC "Os", "K5x"} // Keypad Lower right }}; -constexpr std::array fkey_table = +//---------------------------------------------------------------------- +constexpr FKeyMap::KeyMapType FKeyMap::fkey_table = {{ { FKey::Meta_insert , "\033[2;3~" }, // M-Insert { FKey::Meta_insert , "\033\033[2~" }, // M-Insert @@ -464,7 +488,8 @@ constexpr std::array fkey_table = { FKey::Meta_tilde , "\033~" } // M-~ }}; -constexpr std::array fkeyname = +//---------------------------------------------------------------------- +constexpr FKeyMap::KeyNameType FKeyMap::fkeyname = {{ { FKey::Ctrl_a , "Ctrl+A" }, { FKey::Ctrl_b , "Ctrl+B" }, @@ -856,6 +881,4 @@ constexpr std::array fkeyname = { FKey::Incomplete , "incomplete key string" } }}; -} // namespace fc - } // namespace finalcut diff --git a/src/fkeyboard.cpp b/src/fkeyboard.cpp index 5dc8caae..6b54c128 100644 --- a/src/fkeyboard.cpp +++ b/src/fkeyboard.cpp @@ -91,17 +91,19 @@ void FKeyboard::fetchKeyCode() //---------------------------------------------------------------------- FString FKeyboard::getKeyName (const FKey keynum) const { + const auto& fkeyname = FKeyMap::getInstance().getKeyName(); + const auto& found_key = std::find_if ( - fc::fkeyname.cbegin(), - fc::fkeyname.cend(), - [&keynum] (const fc::FKeyName& kn) + fkeyname.cbegin(), + fkeyname.cend(), + [&keynum] (const FKeyMap::KeyName& kn) { return ( kn.num != FKey::None && kn.num == keynum ); } ); - if ( found_key != fc::fkeyname.end() ) + if ( found_key != fkeyname.end() ) return {found_key->string}; if ( keynum > 32 && keynum < 127 ) @@ -315,7 +317,7 @@ inline FKey FKeyboard::getKnownKey() assert ( FIFO_BUF_SIZE > 0 ); - for (auto&& entry : fc::fkey_table) + for (auto&& entry : FKeyMap::getInstance().getKeyMap()) { const char* kstr = entry.string; // The string is never null const std::size_t len = stringLength(kstr); diff --git a/src/foptiattr.cpp b/src/foptiattr.cpp index f96cff36..f46241fe 100644 --- a/src/foptiattr.cpp +++ b/src/foptiattr.cpp @@ -888,34 +888,31 @@ inline bool FOptiAttr::unsetTermDoubleUnderline (FChar& term) } //---------------------------------------------------------------------- -bool FOptiAttr::setTermAttributes ( FChar& term - , bool p1, bool p2, bool p3 - , bool p4, bool p5, bool p6 - , bool p7, bool p8, bool p9 ) +bool FOptiAttr::setTermAttributes (FChar& term, const TCapAttributes& attr) { if ( F_set_attributes.cap ) { const auto sgr = FTermcap::encodeParameter ( F_set_attributes.cap - , p1 && ! fake_reverse - , p2 - , p3 && ! fake_reverse - , p4 - , p5 - , p6 - , p7 - , p8 - , p9 ); + , attr.p1 && ! fake_reverse + , attr.p2 + , attr.p3 && ! fake_reverse + , attr.p4 + , attr.p5 + , attr.p6 + , attr.p7 + , attr.p8 + , attr.p9 ); append_sequence (sgr.data()); resetColor(term); - term.attr.bit.standout = p1; - term.attr.bit.underline = p2; - term.attr.bit.reverse = p3; - term.attr.bit.blink = p4; - term.attr.bit.dim = p5; - term.attr.bit.bold = p6; - term.attr.bit.invisible = p7; - term.attr.bit.protect = p8; - term.attr.bit.alt_charset = p9; + term.attr.bit.standout = attr.p1; + term.attr.bit.underline = attr.p2; + term.attr.bit.reverse = attr.p3; + term.attr.bit.blink = attr.p4; + term.attr.bit.dim = attr.p5; + term.attr.bit.bold = attr.p6; + term.attr.bit.invisible = attr.p7; + term.attr.bit.protect = attr.p8; + term.attr.bit.alt_charset = attr.p9; term.attr.bit.pc_charset = false; term.attr.bit.italic = false; term.attr.bit.crossed_out = false; @@ -1243,15 +1240,15 @@ inline void FOptiAttr::changeAttributeSGR (FChar& term, FChar& next) if ( switchOn() || switchOff() ) setTermAttributes ( term - , next.attr.bit.standout - , next.attr.bit.underline - , next.attr.bit.reverse - , next.attr.bit.blink - , next.attr.bit.dim - , next.attr.bit.bold - , next.attr.bit.invisible - , next.attr.bit.protect - , next.attr.bit.alt_charset ); + , { next.attr.bit.standout + , next.attr.bit.underline + , next.attr.bit.reverse + , next.attr.bit.blink + , next.attr.bit.dim + , next.attr.bit.bold + , next.attr.bit.invisible + , next.attr.bit.protect + , next.attr.bit.alt_charset } ); if ( alt_equal_pc_charset && F_enter_pc_charset_mode.cap diff --git a/src/fterm.cpp b/src/fterm.cpp index 21a4df68..db1c8d1a 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -927,15 +927,16 @@ wchar_t FTerm::charEncode (wchar_t c) wchar_t FTerm::charEncode (wchar_t c, Encoding enc) { wchar_t ch_enc = c; - auto found = std::find_if ( fc::character.begin() - , fc::character.end() - , [&c] (const fc::CharEncodeMap& entry) + auto& character = FCharMap::getInstance().getCharEncodeMap(); + auto found = std::find_if ( character.begin() + , character.end() + , [&c] (const FCharMap::CharEncodeMap& entry) { return entry.unicode == c; } ); - if ( found != fc::character.end() ) - ch_enc = getCharacter(*found, enc); + if ( found != character.end() ) + ch_enc = FCharMap::getCharacter(*found, enc); if ( enc == Encoding::PC && ch_enc == c ) ch_enc = finalcut::unicode_to_cp437(c); @@ -1134,6 +1135,7 @@ void FTerm::init_alt_charset() // Read the used VT100 pairs std::unordered_map vt100_alt_char; + auto& character = FCharMap::getInstance().getCharEncodeMap(); if ( TCAP(t_acs_chars) ) { @@ -1147,23 +1149,23 @@ void FTerm::init_alt_charset() } // Update array 'character' with discovered VT100 pairs - for (auto&& pair : fc::dec_special_graphics) + for (auto&& pair : FCharMap::getInstance().getDECSpecialGraphics()) { const auto keyChar = uChar(pair.key); const auto altChar = wchar_t(vt100_alt_char[keyChar]); const auto utf8char = wchar_t(pair.unicode); - const auto p = std::find_if ( fc::character.begin() - , fc::character.end() - , [&utf8char] (fc::CharEncodeMap entry) + const auto p = std::find_if ( character.begin() + , character.end() + , [&utf8char] (FCharMap::CharEncodeMap entry) { return entry.unicode == utf8char; } ); - if ( p != fc::character.end() ) // found in character + if ( p != character.end() ) // found in character { - const auto item = std::size_t(std::distance(fc::character.begin(), p)); + const auto item = std::size_t(std::distance(character.begin(), p)); if ( altChar ) // update alternate character set - getCharacter(fc::character[item], Encoding::VT100) = altChar; + FCharMap::getCharacter(character[item], Encoding::VT100) = altChar; else // delete VT100 char in character - getCharacter(fc::character[item], Encoding::VT100) = L'\0'; + FCharMap::getCharacter(character[item], Encoding::VT100) = L'\0'; } } } @@ -1232,7 +1234,7 @@ void FTerm::init_cygwin_charmap() return; // PC encoding changes - for (auto&& entry : fc::character) + for (auto&& entry : FCharMap::getInstance().getCharEncodeMap()) { if ( entry.unicode == UniChar::BlackUpPointingTriangle ) // ▲ entry.pc = 0x18; @@ -1287,7 +1289,7 @@ void FTerm::init_teraterm_charmap() if ( ! isTeraTerm() ) return; - for (auto&& entry : fc::character) + for (auto&& entry : FCharMap::getInstance().getCharEncodeMap()) if ( entry.pc < 0x20 ) entry.pc = entry.ascii; } diff --git a/src/fterm_functions.cpp b/src/fterm_functions.cpp index fa5056eb..b0ec7984 100644 --- a/src/fterm_functions.cpp +++ b/src/fterm_functions.cpp @@ -53,9 +53,6 @@ enum class FullWidthSupport // Constant constexpr std::size_t NOT_FOUND = static_cast(-1); -// global state -static FullWidthSupport has_fullwidth_support = FullWidthSupport::Unknown; - // Function prototypes bool hasAmbiguousWidth (wchar_t); @@ -259,6 +256,9 @@ bool hasFullWidthSupports() { // Checks if the terminal has full-width character support + // global state + static FullWidthSupport has_fullwidth_support = FullWidthSupport::Unknown; + if ( has_fullwidth_support == FullWidthSupport::Unknown ) { if ( ! FTerm::isInitialized() ) @@ -284,15 +284,16 @@ wchar_t cp437_to_unicode (uChar c) { constexpr std::size_t CP437 = 0; constexpr std::size_t UNICODE = 1; + const auto& cp437_ucs = FCharMap::getInstance().getCP437UCSMap(); wchar_t ucs = c; - auto found = std::find_if ( fc::cp437_ucs.begin() - , fc::cp437_ucs.end() + auto found = std::find_if ( cp437_ucs.begin() + , cp437_ucs.end() , [&c] (const std::array& entry) { return entry[CP437] == c; } ); - if ( found != fc::cp437_ucs.end() ) + if ( found != cp437_ucs.end() ) ucs = (*found)[UNICODE]; return ucs; @@ -303,16 +304,16 @@ uChar unicode_to_cp437 (wchar_t ucs) { constexpr std::size_t CP437 = 0; constexpr std::size_t UNICODE = 1; + const auto& cp437_ucs = FCharMap::getInstance().getCP437UCSMap(); uChar c{'?'}; - - auto found = std::find_if ( fc::cp437_ucs.begin() - , fc::cp437_ucs.end() + auto found = std::find_if ( cp437_ucs.begin() + , cp437_ucs.end() , [&ucs] (const std::array& entry) { return entry[UNICODE] == ucs; } ); - if ( found != fc::cp437_ucs.end() ) + if ( found != cp437_ucs.end() ) c = static_cast((*found)[CP437]); return c; @@ -326,16 +327,17 @@ FString getFullWidth (const FString& str) FString s{str}; auto table_search = [] (wchar_t& c) { + const auto& halfwidth_fullwidth = FCharMap::getInstance().getHalfFullWidthMap(); constexpr std::size_t HALF = 0; constexpr std::size_t FULL = 1; - auto found = std::find_if ( fc::halfwidth_fullwidth.begin() - , fc::halfwidth_fullwidth.end() + auto found = std::find_if ( halfwidth_fullwidth.begin() + , halfwidth_fullwidth.end() , [&c] (const std::array& entry) { return entry[HALF] == c; } ); - if ( found != fc::halfwidth_fullwidth.end() ) + if ( found != halfwidth_fullwidth.end() ) c = (*found)[FULL]; }; @@ -358,16 +360,17 @@ FString getHalfWidth (const FString& str) FString s{str}; auto table_search = [] (wchar_t& c) { + const auto& halfwidth_fullwidth = FCharMap::getInstance().getHalfFullWidthMap(); constexpr std::size_t HALF = 0; constexpr std::size_t FULL = 1; - auto found = std::find_if ( fc::halfwidth_fullwidth.begin() - , fc::halfwidth_fullwidth.end() + auto found = std::find_if ( halfwidth_fullwidth.begin() + , halfwidth_fullwidth.end() , [&c] (const std::array& entry) { return entry[FULL] == c; } ); - if ( found != fc::halfwidth_fullwidth.end() ) + if ( found != halfwidth_fullwidth.end() ) c = (*found)[HALF]; }; diff --git a/src/ftermcap.cpp b/src/ftermcap.cpp index 39bd1d13..9d239a1a 100644 --- a/src/ftermcap.cpp +++ b/src/ftermcap.cpp @@ -426,7 +426,7 @@ void FTermcap::termcapKeys() // Get termcap keys // Read termcap key sequences up to the self-defined values - for (auto&& entry : fc::fkey_cap_table) + for (auto&& entry : FKeyMap::getInstance().getKeyCapMap()) { if ( entry.string != nullptr ) // String is already set break; @@ -437,10 +437,8 @@ void FTermcap::termcapKeys() //---------------------------------------------------------------------- std::string FTermcap::encodeParams ( const std::string& cap - , const std::vector& param_vec ) + , const std::array& params ) { - std::array params{{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }}; - std::copy (param_vec.begin(), param_vec.end(), params.begin()); auto str = ::tparm ( C_STR(cap.data()), params[0], params[1] , params[2], params[3], params[4], params[5] , params[6], params[7], params[8] ); diff --git a/src/ftermcapquirks.cpp b/src/ftermcapquirks.cpp index e2e2004b..0ce0ed5b 100644 --- a/src/ftermcapquirks.cpp +++ b/src/ftermcapquirks.cpp @@ -370,73 +370,74 @@ void FTermcapQuirks::sunConsole() TCAP(t_parm_down_cursor) = CSI "%p1%dB"; TCAP(t_parm_right_cursor) = CSI "%p1%dC"; TCAP(t_parm_left_cursor) = CSI "%p1%dD"; + auto& fkey_cap_table = FKeyMap::getInstance().getKeyCapMap(); // Sun Microsystems workstation console keys - for (std::size_t i{0}; fc::fkey_cap_table[i].tname[0] != 0; i++) + for (std::size_t i{0}; fkey_cap_table[i].tname[0] != 0; i++) { - if ( std::strncmp(fc::fkey_cap_table[i].tname, "K2", 2) == 0 ) - fc::fkey_cap_table[i].string = CSI "218z"; // center of keypad + if ( std::strncmp(fkey_cap_table[i].tname, "K2", 2) == 0 ) + fkey_cap_table[i].string = CSI "218z"; // center of keypad - if ( std::strncmp(fc::fkey_cap_table[i].tname, "kb", 2) == 0 ) - fc::fkey_cap_table[i].string = "\b"; // backspace key + if ( std::strncmp(fkey_cap_table[i].tname, "kb", 2) == 0 ) + fkey_cap_table[i].string = "\b"; // backspace key - if ( std::strncmp(fc::fkey_cap_table[i].tname, "kD", 2) == 0 - && stringLength(fc::fkey_cap_table[i].tname) == 2 ) - fc::fkey_cap_table[i].string = "\177"; // delete-character key + if ( std::strncmp(fkey_cap_table[i].tname, "kD", 2) == 0 + && stringLength(fkey_cap_table[i].tname) == 2 ) + fkey_cap_table[i].string = "\177"; // delete-character key - if ( std::strncmp(fc::fkey_cap_table[i].tname, "@7", 2) == 0 ) - fc::fkey_cap_table[i].string = CSI "220z"; // end key + if ( std::strncmp(fkey_cap_table[i].tname, "@7", 2) == 0 ) + fkey_cap_table[i].string = CSI "220z"; // end key - if ( std::strncmp(fc::fkey_cap_table[i].tname, "k;", 2) == 0 ) - fc::fkey_cap_table[i].string = CSI "233z"; // F10 function key + if ( std::strncmp(fkey_cap_table[i].tname, "k;", 2) == 0 ) + fkey_cap_table[i].string = CSI "233z"; // F10 function key - if ( std::strncmp(fc::fkey_cap_table[i].tname, "F1", 2) == 0 ) - fc::fkey_cap_table[i].string = CSI "234z"; // F11 function key + if ( std::strncmp(fkey_cap_table[i].tname, "F1", 2) == 0 ) + fkey_cap_table[i].string = CSI "234z"; // F11 function key - if ( std::strncmp(fc::fkey_cap_table[i].tname, "F2", 2) == 0 ) - fc::fkey_cap_table[i].string = CSI "235z"; // F12 function key + if ( std::strncmp(fkey_cap_table[i].tname, "F2", 2) == 0 ) + fkey_cap_table[i].string = CSI "235z"; // F12 function key - if ( std::strncmp(fc::fkey_cap_table[i].tname, "kh", 2) == 0 ) - fc::fkey_cap_table[i].string = CSI "214z"; // home key + if ( std::strncmp(fkey_cap_table[i].tname, "kh", 2) == 0 ) + fkey_cap_table[i].string = CSI "214z"; // home key - if ( std::strncmp(fc::fkey_cap_table[i].tname, "kI", 2) == 0 ) - fc::fkey_cap_table[i].string = CSI "247z"; // insert-character key + if ( std::strncmp(fkey_cap_table[i].tname, "kI", 2) == 0 ) + fkey_cap_table[i].string = CSI "247z"; // insert-character key - if ( std::strncmp(fc::fkey_cap_table[i].tname, "kN", 2) == 0 ) - fc::fkey_cap_table[i].string = CSI "222z"; // next-page key + if ( std::strncmp(fkey_cap_table[i].tname, "kN", 2) == 0 ) + fkey_cap_table[i].string = CSI "222z"; // next-page key - if ( std::strncmp(fc::fkey_cap_table[i].tname, "%7", 2) == 0 ) - fc::fkey_cap_table[i].string = CSI "194z"; // options key + if ( std::strncmp(fkey_cap_table[i].tname, "%7", 2) == 0 ) + fkey_cap_table[i].string = CSI "194z"; // options key - if ( std::strncmp(fc::fkey_cap_table[i].tname, "kP", 2) == 0 ) - fc::fkey_cap_table[i].string = CSI "216z"; // prev-page key + if ( std::strncmp(fkey_cap_table[i].tname, "kP", 2) == 0 ) + fkey_cap_table[i].string = CSI "216z"; // prev-page key - if ( std::strncmp(fc::fkey_cap_table[i].tname, "&5", 2) == 0 ) - fc::fkey_cap_table[i].string = CSI "193z"; // resume key + if ( std::strncmp(fkey_cap_table[i].tname, "&5", 2) == 0 ) + fkey_cap_table[i].string = CSI "193z"; // resume key - if ( std::strncmp(fc::fkey_cap_table[i].tname, "&8", 2) == 0 ) - fc::fkey_cap_table[i].string = CSI "195z"; // undo key + if ( std::strncmp(fkey_cap_table[i].tname, "&8", 2) == 0 ) + fkey_cap_table[i].string = CSI "195z"; // undo key - if ( std::strncmp(fc::fkey_cap_table[i].tname, "K2", 2) == 0 ) - fc::fkey_cap_table[i].string = CSI "218z"; // center of keypad + if ( std::strncmp(fkey_cap_table[i].tname, "K2", 2) == 0 ) + fkey_cap_table[i].string = CSI "218z"; // center of keypad - if ( std::strncmp(fc::fkey_cap_table[i].tname, "kDx", 3) == 0 ) - fc::fkey_cap_table[i].string = CSI "249z"; // keypad delete + if ( std::strncmp(fkey_cap_table[i].tname, "kDx", 3) == 0 ) + fkey_cap_table[i].string = CSI "249z"; // keypad delete - if ( std::strncmp(fc::fkey_cap_table[i].tname, "@8x", 3) == 0 ) - fc::fkey_cap_table[i].string = CSI "250z"; // enter/send key + if ( std::strncmp(fkey_cap_table[i].tname, "@8x", 3) == 0 ) + fkey_cap_table[i].string = CSI "250z"; // enter/send key - if ( std::strncmp(fc::fkey_cap_table[i].tname, "KP1", 3) == 0 ) - fc::fkey_cap_table[i].string = CSI "212z"; // keypad slash + if ( std::strncmp(fkey_cap_table[i].tname, "KP1", 3) == 0 ) + fkey_cap_table[i].string = CSI "212z"; // keypad slash - if ( std::strncmp(fc::fkey_cap_table[i].tname, "KP2", 3) == 0 ) - fc::fkey_cap_table[i].string = CSI "213z"; // keypad asterisk + if ( std::strncmp(fkey_cap_table[i].tname, "KP2", 3) == 0 ) + fkey_cap_table[i].string = CSI "213z"; // keypad asterisk - if ( std::strncmp(fc::fkey_cap_table[i].tname, "KP3", 3) == 0 ) - fc::fkey_cap_table[i].string = CSI "254z"; // keypad minus sign + if ( std::strncmp(fkey_cap_table[i].tname, "KP3", 3) == 0 ) + fkey_cap_table[i].string = CSI "254z"; // keypad minus sign - if ( std::strncmp(fc::fkey_cap_table[i].tname, "KP4", 3) == 0 ) - fc::fkey_cap_table[i].string = CSI "253z"; // keypad plus sign + if ( std::strncmp(fkey_cap_table[i].tname, "KP4", 3) == 0 ) + fkey_cap_table[i].string = CSI "253z"; // keypad plus sign } } diff --git a/src/ftermfreebsd.cpp b/src/ftermfreebsd.cpp index 8726a293..a3b58236 100644 --- a/src/ftermfreebsd.cpp +++ b/src/ftermfreebsd.cpp @@ -155,7 +155,7 @@ void FTermFreeBSD::initCharMap() if ( ! isFreeBSDConsole() ) return; - for (auto&& entry : fc::character) + for (auto&& entry : FCharMap::getInstance().getCharEncodeMap()) if ( entry.pc < 0x1c ) entry.pc = entry.ascii; } diff --git a/src/ftermlinux.cpp b/src/ftermlinux.cpp index 7185c2dc..bb7c3ad4 100644 --- a/src/ftermlinux.cpp +++ b/src/ftermlinux.cpp @@ -215,7 +215,7 @@ void FTermLinux::initCharMap() const if ( screen_unicode_map.entry_ct > 0 && screen_unicode_map.entries ) { - for (auto&& entry : fc::character) + for (auto&& entry : FCharMap::getInstance().getCharEncodeMap()) { const auto ucs = entry.unicode; const sInt16 fontpos = getFontPos(ucs); diff --git a/src/ftooltip.cpp b/src/ftooltip.cpp index fb48762d..d5e749c2 100644 --- a/src/ftooltip.cpp +++ b/src/ftooltip.cpp @@ -42,7 +42,7 @@ FToolTip::FToolTip (FWidget* parent) //---------------------------------------------------------------------- FToolTip::FToolTip (const FString& txt, FWidget* parent) : FWindow{parent} - , text{txt} + , text{txt.trim()} { init(); } @@ -69,7 +69,7 @@ FToolTip::~FToolTip() // destructor //---------------------------------------------------------------------- void FToolTip::setText (const FString& txt) { - text.setString(txt); + text.setString(txt.trim()); calculateDimensions(); } diff --git a/src/include/final/fcharmap.h b/src/include/final/fcharmap.h index 8980e602..96c83b05 100644 --- a/src/include/final/fcharmap.h +++ b/src/include/final/fcharmap.h @@ -3,7 +3,7 @@ * * * This file is part of the FINAL CUT widget toolkit * * * -* Copyright 2015-2020 Markus Gans * +* Copyright 2015-2021 Markus Gans * * * * FINAL CUT is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -30,43 +30,63 @@ #include #include "final/fc.h" +#include "final/fstring.h" #include "final/ftypes.h" + namespace finalcut { -namespace fc +class FCharMap final { + public: + // Unicode fallback table for VT100, PC, and ASCII + struct CharEncodeMap + { + wchar_t unicode; + wchar_t vt100; + wchar_t pc; + wchar_t ascii; + }; -// Unicode fallback table for VT100, PC, and ASCII -struct CharEncodeMap -{ - wchar_t unicode; - wchar_t vt100; - wchar_t pc; - wchar_t ascii; + // vt100 <-> utf-8 + struct DECSpecialGraphics + { + VT100Key key; + UniChar unicode; + }; + + // Using-declaration + using CharEncodeType = std::array; + using DECGraphicsType = std::array; + using Cp437UcsType = std::array, 256>; + using HalfFullWidthType = std::array, 227>; + + // Constructors + FCharMap() = default; + + // Accessors + FString getClassName() const; + static auto getInstance() -> FCharMap&; + static wchar_t& getCharacter ( CharEncodeMap& char_enc + , const Encoding& enc ); + static CharEncodeType& getCharEncodeMap(); + static const DECGraphicsType& getDECSpecialGraphics(); + static const Cp437UcsType& getCP437UCSMap(); + static const HalfFullWidthType& getHalfFullWidthMap(); + + private: + // Data members + static CharEncodeType character; + static const DECGraphicsType dec_special_graphics; + static const Cp437UcsType cp437_ucs; + static const HalfFullWidthType halfwidth_fullwidth; }; -extern std::array character; - -inline wchar_t& getCharacter (CharEncodeMap& char_enc, const Encoding& enc) -{ - const auto array = reinterpret_cast(&char_enc); - return array[std::size_t(enc)]; -} - -// vt100 <-> utf-8 -struct DECSpecialGraphics -{ - VT100Key key; - UniChar unicode; -}; - -extern const std::array dec_special_graphics; -extern const std::array, 256> cp437_ucs; -extern const std::array, 227> halfwidth_fullwidth; - -} // namespace fc +// FCharMap inline functions +//---------------------------------------------------------------------- +inline FString FCharMap::getClassName() const +{ return "FCharMap"; } } // namespace finalcut diff --git a/src/include/final/fkey_map.h b/src/include/final/fkey_map.h index ca33d5ac..21540957 100644 --- a/src/include/final/fkey_map.h +++ b/src/include/final/fkey_map.h @@ -3,7 +3,7 @@ * * * This file is part of the FINAL CUT widget toolkit * * * -* Copyright 2015-2020 Markus Gans * +* Copyright 2015-2021 Markus Gans * * * * FINAL CUT is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -29,6 +29,7 @@ #include +#include "final/fstring.h" #include "final/ftypes.h" namespace finalcut @@ -36,35 +37,54 @@ namespace finalcut enum class FKey : uInt32; // forward declaration -namespace fc +class FKeyMap final { + public: + struct KeyCapMap + { + FKey num; + const char* string; + char tname[4]; + }; -struct FKeyCapMap -{ - FKey num; - const char* string; - char tname[4]; + struct KeyMap + { + FKey num; + char string[8]; + }; + + struct KeyName + { + FKey num; + char string[26]; + }; + + // Using-declaration + using KeyCapMapType = std::array; + using KeyMapType = std::array; + using KeyNameType = std::array; + + // Constructors + FKeyMap() = default; + + // Accessors + FString getClassName() const; + static auto getInstance() -> FKeyMap&; + static KeyCapMapType& getKeyCapMap(); + static const KeyMapType& getKeyMap(); + static const KeyNameType& getKeyName(); + + private: + // Data members + static KeyCapMapType fkey_cap_table; + static const KeyMapType fkey_table; + static const KeyNameType fkeyname; }; -extern std::array fkey_cap_table; - -struct FKeyMap -{ - FKey num; - char string[8]; -}; - -extern const std::array fkey_table; - -struct FKeyName -{ - FKey num; - char string[26]; -}; - -extern const std::array fkeyname; - -} // namespace fc +// FKeyMap inline functions +//---------------------------------------------------------------------- +inline FString FKeyMap::getClassName() const +{ return "FKeyMap"; } } // namespace finalcut diff --git a/src/include/final/fkeyboard.h b/src/include/final/fkeyboard.h index d55f89b6..15fb8d83 100644 --- a/src/include/final/fkeyboard.h +++ b/src/include/final/fkeyboard.h @@ -146,7 +146,7 @@ class FKeyboard final private: // Using-declaration - using FKeyMapPtr = std::shared_ptr; + using FKeyMapPtr = std::shared_ptr; // Constants static constexpr FKey NOT_SET = static_cast(-1); @@ -234,8 +234,8 @@ inline void FKeyboard::setTermcapMap (const T& keymap) //---------------------------------------------------------------------- inline void FKeyboard::setTermcapMap () { - using type = decltype(fc::fkey_cap_table); - key_map = std::make_shared(fc::fkey_cap_table); + using type = FKeyMap::KeyCapMapType; + key_map = std::make_shared(FKeyMap::getInstance().getKeyCapMap()); } //---------------------------------------------------------------------- diff --git a/src/include/final/foptiattr.h b/src/include/final/foptiattr.h index d8145483..45f776a2 100644 --- a/src/include/final/foptiattr.h +++ b/src/include/final/foptiattr.h @@ -39,6 +39,7 @@ #include // need for std::swap #include "final/fstring.h" +#include "final/ftypes.h" #include "final/sgr_optimizer.h" namespace finalcut @@ -222,10 +223,7 @@ class FOptiAttr final bool unsetTermCrossedOut (FChar&); bool setTermDoubleUnderline (FChar&); bool unsetTermDoubleUnderline (FChar&); - bool setTermAttributes ( FChar& - , bool, bool, bool - , bool, bool, bool - , bool, bool, bool ); + bool setTermAttributes (FChar&, const TCapAttributes&); bool unsetTermAttributes (FChar&); bool setTermAltCharset (FChar&); bool unsetTermAltCharset (FChar&); diff --git a/src/include/final/ftermcap.h b/src/include/final/ftermcap.h index 5e6ecf8e..562981ef 100644 --- a/src/include/final/ftermcap.h +++ b/src/include/final/ftermcap.h @@ -41,6 +41,8 @@ #include #include +#include "final/ftypes.h" + // FTermcap string macro #define TCAP(...) FTermcap::strings[int(Termcap::__VA_ARGS__)].string @@ -129,7 +131,7 @@ class FTermcap final static void termcapStrings(); static void termcapKeys(); static std::string encodeParams ( const std::string& - , const std::vector& ); + , const std::array& ); template static void delay_output (int, const PutChar&); @@ -149,7 +151,9 @@ inline FString FTermcap::getClassName() const template std::string FTermcap::encodeParameter (const std::string& cap, Args&&... args) { - return encodeParams(cap, {static_cast(args)...}); + std::array attr{{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }}; + attr = {{static_cast(args)...}}; + return encodeParams(cap, attr); } //---------------------------------------------------------------------- diff --git a/src/include/final/ftypes.h b/src/include/final/ftypes.h index 02dab549..d7093c24 100644 --- a/src/include/final/ftypes.h +++ b/src/include/final/ftypes.h @@ -134,6 +134,20 @@ constexpr std::size_t stringLength (const CharT* s) using charSubstitution = std::unordered_map; +struct TCapAttributes +{ + uInt8 p1 : 1; // Standout + uInt8 p2 : 1; // Underline + uInt8 p3 : 1; // Reverse + uInt8 p4 : 1; // Blink + uInt8 p5 : 1; // Dim + uInt8 p6 : 1; // Bold + uInt8 p7 : 1; // Invisible + uInt8 p8 : 1; // Protected + uInt8 p9 : 1; // Alternate charset + uInt8 : 7; // padding bits +}; + struct FCharAttribute { // Attribute byte #0 diff --git a/test/fkeyboard-test.cpp b/test/fkeyboard-test.cpp index 573f8d36..bad52018 100644 --- a/test/fkeyboard-test.cpp +++ b/test/fkeyboard-test.cpp @@ -77,7 +77,7 @@ struct FKeyCapMap char tname[4]; }; -using original_type = std::array; +using original_type = finalcut::FKeyMap::KeyCapMapType; using test_type = std::array; test_type fkey = diff --git a/test/ftermcapquirks-test.cpp b/test/ftermcapquirks-test.cpp index e0738bea..61db97bd 100644 --- a/test/ftermcapquirks-test.cpp +++ b/test/ftermcapquirks-test.cpp @@ -688,92 +688,93 @@ void FTermcapQuirksTest::sunTest() , CSI "%p1%dC" ); CPPUNIT_ASSERT_CSTRING ( caps[int(finalcut::Termcap::t_parm_left_cursor)].string , CSI "%p1%dD" ); + auto& fkey_cap_table = finalcut::FKeyMap::getInstance().getKeyCapMap(); - for (std::size_t i = 0; finalcut::fc::fkey_cap_table[i].tname[0] != 0; i++) + for (std::size_t i = 0; fkey_cap_table[i].tname[0] != 0; i++) { - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "K2", 2) == 0 ) // center of keypad - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "K2", 2) == 0 ) // center of keypad + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , CSI "218z" ); - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "kb", 2) == 0 ) // backspace key - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "kb", 2) == 0 ) // backspace key + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , "\b" ); - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "kD", 2) == 0 - && std::strlen(finalcut::fc::fkey_cap_table[i].tname) == 2 ) // delete-character key - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "kD", 2) == 0 + && std::strlen(fkey_cap_table[i].tname) == 2 ) // delete-character key + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , "\177" ); - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "@7", 2) == 0 ) // end key - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "@7", 2) == 0 ) // end key + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , CSI "220z" ); - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "k;", 2) == 0 ) // F10 function key - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "k;", 2) == 0 ) // F10 function key + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , CSI "233z" ); - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "F1", 2) == 0 ) // F11 function key - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "F1", 2) == 0 ) // F11 function key + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , CSI "234z" ); - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "F2", 2) == 0 ) // F12 function key - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "F2", 2) == 0 ) // F12 function key + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , CSI "235z" ); - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "kh", 2) == 0 ) // home key - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "kh", 2) == 0 ) // home key + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , CSI "214z" ); - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "kI", 2) == 0 ) // insert-character key - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "kI", 2) == 0 ) // insert-character key + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , CSI "247z" ); - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "kN", 2) == 0 ) // next-page key - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "kN", 2) == 0 ) // next-page key + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , CSI "222z" ); - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "%7", 2) == 0 ) // options key - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "%7", 2) == 0 ) // options key + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , CSI "194z" ); - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "kP", 2) == 0 ) // prev-page key - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "kP", 2) == 0 ) // prev-page key + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , CSI "216z" ); - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "&5", 2) == 0 ) // resume key - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "&5", 2) == 0 ) // resume key + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , CSI "193z" ); - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "&8", 2) == 0 ) // undo key - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "&8", 2) == 0 ) // undo key + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , CSI "195z" ); - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "K2", 2) == 0 ) // center of keypad - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "K2", 2) == 0 ) // center of keypad + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , CSI "218z" ); - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "kDx", 3) == 0 ) // keypad delete - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "kDx", 3) == 0 ) // keypad delete + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , CSI "249z" ); - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "@8x", 3) == 0 ) // enter/send key - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "@8x", 3) == 0 ) // enter/send key + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , CSI "250z" ); - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "KP1", 3) == 0 ) // keypad slash - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "KP1", 3) == 0 ) // keypad slash + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , CSI "212z" ); - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "KP2", 3) == 0 ) // keypad asterisk - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "KP2", 3) == 0 ) // keypad asterisk + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , CSI "213z" ); - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "KP3", 3) == 0 ) // keypad minus sign - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "KP3", 3) == 0 ) // keypad minus sign + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , CSI "254z" ); - if ( std::strncmp(finalcut::fc::fkey_cap_table[i].tname, "KP4", 3) == 0 ) // keypad plus sign - CPPUNIT_ASSERT_CSTRING ( finalcut::fc::fkey_cap_table[i].string + if ( std::strncmp(fkey_cap_table[i].tname, "KP4", 3) == 0 ) // keypad plus sign + CPPUNIT_ASSERT_CSTRING ( fkey_cap_table[i].string , CSI "253z" ); } diff --git a/test/ftermfreebsd-test.cpp b/test/ftermfreebsd-test.cpp index 41fbff87..6ab81490 100644 --- a/test/ftermfreebsd-test.cpp +++ b/test/ftermfreebsd-test.cpp @@ -828,7 +828,7 @@ wchar_t ftermfreebsdTest::charEncode (wchar_t c) { wchar_t ch_enc{L'\0'}; - for (auto&& entry : finalcut::fc::character) + for (auto&& entry : finalcut::FCharMap::getInstance().getCharEncodeMap()) { if ( entry.unicode == c ) {