From 06bfb8bc64a2256bf60b83998fb3b21a36bc27cd Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Tue, 2 Jan 2018 20:38:45 +0100 Subject: [PATCH] Refactoring of secondary device attributes parsing --- ChangeLog | 4 + examples/ui.cpp | 6 +- include/final/flistview.h | 6 +- include/final/foptimove.h | 4 +- include/final/fterm.h | 48 +++- include/final/fvterm.h | 88 +++---- src/fapplication.cpp | 16 +- src/fbutton.cpp | 4 +- src/fbuttongroup.cpp | 8 +- src/flistview.cpp | 18 +- src/fmenu.cpp | 4 +- src/fobject.cpp | 8 +- src/foptiattr.cpp | 27 +- src/foptimove.cpp | 6 +- src/fstring.cpp | 2 +- src/fterm.cpp | 532 +++++++++++++++++++++++--------------- src/fvterm.cpp | 11 +- 17 files changed, 459 insertions(+), 333 deletions(-) diff --git a/ChangeLog b/ChangeLog index d9a50829..def42f60 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2017-01-02 Markus Gans + * Refactoring of secondary device attributes parsing + * Small menu improvements + 2017-12-31 Markus Gans * Refactoring of the FListBox mouse event handler * Refactoring of the FMenuBar mouse event handler diff --git a/examples/ui.cpp b/examples/ui.cpp index 6637c345..3aaaee49 100644 --- a/examples/ui.cpp +++ b/examples/ui.cpp @@ -3,7 +3,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2012-2017 Markus Gans * +* Copyright 2012-2018 Markus Gans * * * * The Final Cut is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public License * @@ -780,7 +780,7 @@ void MyDialog::cb_about (FWidget*, data_ptr) FMessageBox info ( "About" , line + L" The Final Cut " + line + "\n\n" L"Version " + libver + "\n\n" - L"(c) 2017 by Markus Gans" + L"(c) 2018 by Markus Gans" , FMessageBox::Ok, 0, 0, this ); info.setCenterText(); info.show(); @@ -1006,7 +1006,7 @@ void MyDialog::cb_setInput (FWidget* widget, data_ptr data) int main (int argc, char* argv[]) { FString ver = F_VERSION; // Library version - FString title = "The FINAL CUT " + ver + " (C) 2017 by Markus Gans"; + FString title = "The FINAL CUT " + ver + " (C) 2018 by Markus Gans"; // Create the application object app FApplication app(argc, argv); diff --git a/include/final/flistview.h b/include/final/flistview.h index 6d984df3..8784d635 100644 --- a/include/final/flistview.h +++ b/include/final/flistview.h @@ -3,7 +3,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2017 Markus Gans * +* Copyright 2017-2018 Markus Gans * * * * The Final Cut is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public License * @@ -174,8 +174,8 @@ class FListViewIterator FListViewIterator operator ++ (int); // postfix FListViewIterator& operator -- (); // prefix FListViewIterator operator -- (int); // postfix - FListViewIterator& operator += (int); - FListViewIterator& operator -= (int); + FListViewIterator& operator += (volatile int); + FListViewIterator& operator -= (volatile int); FObject*& operator * () const; FObject* operator -> () const; bool operator == (const FListViewIterator&) const; diff --git a/include/final/foptimove.h b/include/final/foptimove.h index 4940a540..3840f4b3 100644 --- a/include/final/foptimove.h +++ b/include/final/foptimove.h @@ -3,7 +3,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2015-2017 Markus Gans * +* Copyright 2015-2018 Markus Gans * * * * The Final Cut is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public License * @@ -133,7 +133,7 @@ class FOptiMove void calculateCharDuration(); int capDuration (char[], int); int capDurationToLength (int); - int repeatedAppend (const capability&, int, char*); + int repeatedAppend (const capability&, volatile int, char*); int relativeMove (char[], int, int, int, int); bool isWideMove (int, int, int, int); bool isMethod0Faster (int&, int, int); diff --git a/include/final/fterm.h b/include/final/fterm.h index 02ee3bdf..a999f728 100644 --- a/include/final/fterm.h +++ b/include/final/fterm.h @@ -3,7 +3,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2012-2017 Markus Gans * +* Copyright 2012-2018 Markus Gans * * * * The Final Cut is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public License * @@ -414,16 +414,6 @@ class FTerm uChar blue; } dacreg; - typedef struct - { - char* string1; - char* string2; - char* string3; - char* string4; - char* string5; - char* string6; - } colorEnv; - // Constants static const int NEED_MORE_DATA = -1; // parseKeyString return value @@ -493,12 +483,21 @@ class FTerm static void init_global_values(); static void detectTerminal(); static void termtypeAnalysis(); - static bool get256colorEnvString (colorEnv&); - static char* termtype_256color_quirks (colorEnv&); + static bool get256colorEnvString(); + static char* termtype_256color_quirks(); static char* init_256colorTerminal(); static char* determineMaxColor (char[]); static char* parseAnswerbackMsg (char[]); static char* parseSecDA (char[]); + static char* secDA_Analysis (char[]); + static char* secDA_Analysis_0 (char[]); + static char* secDA_Analysis_1 (char[]); + static char* secDA_Analysis_24 (char[]); + static char* secDA_Analysis_32 (char[]); + static char* secDA_Analysis_77 (char[]); + static char* secDA_Analysis_82 (char[]); + static char* secDA_Analysis_83 (char[]); + static char* secDA_Analysis_85 (char[]); static void oscPrefix(); static void oscPostfix(); static void init_alt_charset(); @@ -617,6 +616,29 @@ class FTerm static const FString* answer_back; static const FString* sec_da; + static struct colorEnv + { + char* string1; + char* string2; + char* string3; + char* string4; + char* string5; + char* string6; + } color_env; + + static struct secondaryDA + { + secondaryDA() + : terminal_id_type (-1) + , terminal_id_version (-1) + , terminal_id_hardware (-1) + { } + + int terminal_id_type; + int terminal_id_version; + int terminal_id_hardware; + } secondary_da; + struct { dacreg d[16]; diff --git a/include/final/fvterm.h b/include/final/fvterm.h index fcd3646d..c04ba303 100644 --- a/include/final/fvterm.h +++ b/include/final/fvterm.h @@ -3,7 +3,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2016-2017 Markus Gans * +* Copyright 2016-2018 Markus Gans * * * * The Final Cut is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public License * @@ -436,52 +436,52 @@ class FVTerm : public FTerm struct FVTerm::term_area // define virtual terminal character properties { public: - term_area() - : offset_left (0) - , offset_top (0) - , width (-1) - , height (-1) - , right_shadow (0) - , bottom_shadow (0) - , cursor_x (0) - , cursor_y (0) - , input_cursor_x (-1) - , input_cursor_y (-1) - , widget() - , preprocessing_call() - , changes (0) - , text (0) - , input_cursor_visible (false) - , has_changes (false) - , visible (false) - { } + term_area() + : offset_left (0) + , offset_top (0) + , width (-1) + , height (-1) + , right_shadow (0) + , bottom_shadow (0) + , cursor_x (0) + , cursor_y (0) + , input_cursor_x (-1) + , input_cursor_y (-1) + , widget() + , preprocessing_call() + , changes (0) + , text (0) + , input_cursor_visible (false) + , has_changes (false) + , visible (false) + { } - ~term_area() - { } + ~term_area() + { } - int offset_left; // Distance from left terminal side - int offset_top; // Distance from top of the terminal - int width; // Window width - int height; // Window height - int right_shadow; // Right window shadow - int bottom_shadow; // Bottom window shadow - int cursor_x; // X-position for the next write operation - int cursor_y; // Y-position for the next write operation - int input_cursor_x; // X-position input cursor - int input_cursor_y; // Y-position input cursor - FWidget* widget; // Widget that owns this term_area - FPreprocessing preprocessing_call; - line_changes* changes; - char_data* text; // Text data for the output - bool input_cursor_visible; - bool has_changes; - bool visible; + int offset_left; // Distance from left terminal side + int offset_top; // Distance from top of the terminal + int width; // Window width + int height; // Window height + int right_shadow; // Right window shadow + int bottom_shadow; // Bottom window shadow + int cursor_x; // X-position for the next write operation + int cursor_y; // Y-position for the next write operation + int input_cursor_x; // X-position input cursor + int input_cursor_y; // Y-position input cursor + FWidget* widget; // Widget that owns this term_area + FPreprocessing preprocessing_call; + line_changes* changes; + char_data* text; // Text data for the output + bool input_cursor_visible; + bool has_changes; + bool visible; - private: - // Disable copy constructor - term_area (const term_area&); - // Disable assignment operator (=) - term_area& operator = (const term_area&); + private: + // Disable copy constructor + term_area (const term_area&); + // Disable assignment operator (=) + term_area& operator = (const term_area&); }; #pragma pack(pop) diff --git a/src/fapplication.cpp b/src/fapplication.cpp index 9565ee27..c5b7e625 100644 --- a/src/fapplication.cpp +++ b/src/fapplication.cpp @@ -3,7 +3,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2013-2017 Markus Gans * +* Copyright 2013-2018 Markus Gans * * * * The Final Cut is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public License * @@ -335,7 +335,7 @@ void FApplication::showParameterUsage() << " --encoding " << " Sets the character encoding mode" << std::endl << " " - << " {UTF8, VT100, PC, ASCII}" << std::endl + << " {utf8, vt100, pc, ascii}" << std::endl << " --no-optimized-cursor " << " Disable cursor optimization" << std::endl << " --no-terminal-detection" @@ -433,17 +433,17 @@ void FApplication::cmd_options (const int& argc, char* argv[]) if ( std::strcmp(long_options[idx].name, "encoding") == 0 ) { FString encoding(optarg); - encoding = encoding.toUpper(); + encoding = encoding.toLower(); - if ( encoding.includes("UTF8") ) + if ( encoding.includes("utf8") ) init_values.encoding = fc::UTF8; - else if ( encoding.includes("VT100") ) + else if ( encoding.includes("vt100") ) init_values.encoding = fc::VT100; - else if ( encoding.includes("PC") ) + else if ( encoding.includes("pc") ) init_values.encoding = fc::PC; - else if ( encoding.includes("ASCII") ) + else if ( encoding.includes("ascii") ) init_values.encoding = fc::ASCII; - else if ( encoding.includes("HELP") ) + else if ( encoding.includes("help") ) showParameterUsage(); else exitWithMessage ( "Unknown encoding " diff --git a/src/fbutton.cpp b/src/fbutton.cpp index 40b98eaa..fdd3b5e9 100644 --- a/src/fbutton.cpp +++ b/src/fbutton.cpp @@ -3,7 +3,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2012-2017 Markus Gans * +* Copyright 2012-2018 Markus Gans * * * * The Final Cut is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public License * @@ -724,7 +724,7 @@ inline void FButton::drawButtonTextLine (wchar_t button_text[]) } } - if ( txtlength > getWidth() - 2 ) + if ( txtlength >= getWidth() - 1 ) { // Print ellipsis setPrintPos (getWidth() + indent - 2, 1); diff --git a/src/fbuttongroup.cpp b/src/fbuttongroup.cpp index 650f8555..da67c9f5 100644 --- a/src/fbuttongroup.cpp +++ b/src/fbuttongroup.cpp @@ -4,7 +4,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2014-2017 Markus Gans * +* Copyright 2014-2018 Markus Gans * * * * The Final Cut is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public License * @@ -75,16 +75,14 @@ FButtonGroup::~FButtonGroup() // destructor FToggleButton* FButtonGroup::getButton (int index) const { constFObjectIterator iter; - index--; - if ( buttonlist.empty() ) return 0; - if ( index < 0 || index >= int(getCount()) ) + if ( index <= 0 || index > int(getCount()) ) return 0; iter = buttonlist.begin(); - std::advance (iter, index); + std::advance (iter, index - 1); return static_cast(*iter); } diff --git a/src/flistview.cpp b/src/flistview.cpp index c03204b0..72a937a0 100644 --- a/src/flistview.cpp +++ b/src/flistview.cpp @@ -3,7 +3,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2017 Markus Gans * +* Copyright 2017-2018 Markus Gans * * * * The Final Cut is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public License * @@ -321,7 +321,7 @@ FListViewIterator FListViewIterator::operator -- (int) // postfix } //---------------------------------------------------------------------- -FListViewIterator& FListViewIterator::operator += (int n) +FListViewIterator& FListViewIterator::operator += (volatile int n) { while ( n > 0 ) { @@ -333,7 +333,7 @@ FListViewIterator& FListViewIterator::operator += (int n) } //---------------------------------------------------------------------- -FListViewIterator& FListViewIterator::operator -= (int n) +FListViewIterator& FListViewIterator::operator -= (volatile int n) { while ( n > 0 ) { @@ -1093,7 +1093,7 @@ void FListView::onWheel (FWheelEvent* ev) if ( current_iter.getPosition() == 0 ) break; - if ( first_visible_line.getPosition() - pagesize >= 0 ) + if ( first_visible_line.getPosition() >= pagesize ) { current_iter -= pagesize; first_visible_line -= pagesize; @@ -1116,7 +1116,7 @@ void FListView::onWheel (FWheelEvent* ev) if ( current_iter.getPosition() + 1 == element_count ) break; - if ( last_visible_line.getPosition() + pagesize < element_count ) + if ( last_visible_line.getPosition() < element_count - pagesize ) { current_iter += pagesize; first_visible_line += pagesize; @@ -1197,17 +1197,17 @@ void FListView::adjustViewport() int difference = first_visible_line.getPosition() - (element_count - height); - if ( first_visible_line.getPosition() - difference + 1 > 0 ) + if ( first_visible_line.getPosition() >= difference ) { first_visible_line -= difference; last_visible_line -= difference; } } - int max_last_visible_line = first_visible_line.getPosition() - + height - 1; + int after_last_visible_line = first_visible_line.getPosition() + + height; - if ( last_visible_line.getPosition() > max_last_visible_line ) + if ( last_visible_line.getPosition() >= after_last_visible_line ) { last_visible_line = first_visible_line; last_visible_line += height - 1; diff --git a/src/fmenu.cpp b/src/fmenu.cpp index f3911b15..dae2baa9 100644 --- a/src/fmenu.cpp +++ b/src/fmenu.cpp @@ -3,7 +3,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2015-2017 Markus Gans * +* Copyright 2015-2018 Markus Gans * * * * The Final Cut is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public License * @@ -212,8 +212,6 @@ void FMenu::onKeyPress (FKeyEvent* ev) //---------------------------------------------------------------------- void FMenu::onMouseDown (FMouseEvent* ev) { - std::vector::const_iterator iter, last; - FPoint mouse_pos; shown_sub_menu = 0; if ( ev->getButton() != fc::LeftButton ) diff --git a/src/fobject.cpp b/src/fobject.cpp index 6006e222..f4ed50bc 100644 --- a/src/fobject.cpp +++ b/src/fobject.cpp @@ -3,7 +3,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2015-2017 Markus Gans * +* Copyright 2015-2018 Markus Gans * * * * The Final Cut is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public License * @@ -102,17 +102,15 @@ FObject::~FObject() // destructor //---------------------------------------------------------------------- FObject* FObject::getChild (int index) const { - index--; - if ( ! hasChildren() ) return 0; - if ( index < 0 || index >= numOfChildren() ) + if ( index <= 0 || index > numOfChildren() ) return 0; constFObjectIterator iter; iter = begin(); - std::advance (iter, index); + std::advance (iter, index - 1); return *iter; } diff --git a/src/foptiattr.cpp b/src/foptiattr.cpp index 4f0300aa..2519b72b 100644 --- a/src/foptiattr.cpp +++ b/src/foptiattr.cpp @@ -1214,13 +1214,11 @@ inline void FOptiAttr::prevent_no_color_video_attributes (char_data*& attr) switch ( bit & attr_without_color ) { case standout_mode: - if ( attr->attr.bit.standout ) - attr->attr.bit.standout = false; + attr->attr.bit.standout = false; break; case underline_mode: - if ( attr->attr.bit.underline ) - attr->attr.bit.underline = false; + attr->attr.bit.underline = false; break; case reverse_mode: @@ -1234,38 +1232,31 @@ inline void FOptiAttr::prevent_no_color_video_attributes (char_data*& attr) break; case blink_mode: - if ( attr->attr.bit.blink ) - attr->attr.bit.blink = false; + attr->attr.bit.blink = false; break; case dim_mode: - if ( attr->attr.bit.dim ) - attr->attr.bit.dim = false; + attr->attr.bit.dim = false; break; case bold_mode: - if ( attr->attr.bit.bold ) - attr->attr.bit.bold = false; + attr->attr.bit.bold = false; break; case invisible_mode: - if ( attr->attr.bit.invisible ) - attr->attr.bit.invisible = false; + attr->attr.bit.invisible = false; break; case protected_mode: - if ( attr->attr.bit.protect ) - attr->attr.bit.protect = false; + attr->attr.bit.protect = false; break; case alt_charset_mode: - if ( attr->attr.bit.alt_charset ) - attr->attr.bit.alt_charset = false; + attr->attr.bit.alt_charset = false; break; case italic_mode: - if ( attr->attr.bit.italic ) - attr->attr.bit.italic = false; + attr->attr.bit.italic = false; break; default: diff --git a/src/foptimove.cpp b/src/foptimove.cpp index f0de6999..27df555d 100644 --- a/src/foptimove.cpp +++ b/src/foptimove.cpp @@ -3,7 +3,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2015-2017 Markus Gans * +* Copyright 2015-2018 Markus Gans * * * * The Final Cut is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public License * @@ -639,7 +639,9 @@ int FOptiMove::capDurationToLength (int duration) } //---------------------------------------------------------------------- -int FOptiMove::repeatedAppend (const capability& o, int count, char* dst) +int FOptiMove::repeatedAppend ( const capability& o + , volatile int count + , char* dst ) { register std::size_t src_len; register std::size_t dst_len; diff --git a/src/fstring.cpp b/src/fstring.cpp index a9e29cc6..f5434277 100644 --- a/src/fstring.cpp +++ b/src/fstring.cpp @@ -3,7 +3,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2012-2017 Markus Gans * +* Copyright 2012-2018 Markus Gans * * * * The Final Cut is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public License * diff --git a/src/fterm.cpp b/src/fterm.cpp index fd7beb52..f673d491 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -3,7 +3,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2012-2017 Markus Gans * +* Copyright 2012-2018 Markus Gans * * * * The Final Cut is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public License * @@ -138,6 +138,8 @@ bool FTermcap::no_utf8_acs_chars = false; int FTermcap::max_color = 1; int FTermcap::tabstop = 8; int FTermcap::attr_without_color = 0; +FTerm::secondaryDA FTerm::secondary_da; +FTerm::colorEnv FTerm::color_env; FTerm::initializationValues FTerm::init_values; fc::linuxConsoleCursorStyle FTerm::linux_console_cursor_style; fc::freebsdConsoleCursorStyle FTerm::freebsd_console_cursor_style; @@ -493,9 +495,7 @@ int FTerm::parseKeyString ( char buffer[] if ( k && std::strncmp(k, buffer, uInt(len)) == 0 ) // found { - n = len; - - for (; n < buf_size; n++) // Remove founded entry + for (n = len; n < buf_size; n++) // Remove founded entry buffer[n - len] = buffer[n]; for (; n - len < len; n++) // Fill rest with '\0' @@ -521,9 +521,8 @@ int FTerm::parseKeyString ( char buffer[] if ( ! isKeyTimeout(time_keypressed, key_timeout) ) return NEED_MORE_DATA; } - n = len; - for (; n < buf_size; n++) // Remove founded entry + for (n = len; n < buf_size; n++) // Remove founded entry buffer[n - len] = buffer[n]; for (; n - len < len; n++) // Fill rest with '\0' @@ -561,9 +560,7 @@ int FTerm::parseKeyString ( char buffer[] else key = uChar(buffer[0] & 0xff); - n = len; - - for (; n < buf_size; n++) // remove the key from the buffer front + for (n = len; n < buf_size; n++) // remove the key from the buffer front buffer[n - len] = buffer[n]; for (n = n - len; n < buf_size; n++) // fill the rest with '\0' bytes @@ -1476,9 +1473,6 @@ void FTerm::beep() //---------------------------------------------------------------------- void FTerm::setEncoding (fc::encoding enc) { - if ( FTermcap::no_utf8_acs_chars && isUTF8() && enc == fc::VT100 ) - enc = fc::UTF8; - term_encoding = enc; assert ( term_encoding == fc::UTF8 @@ -1486,7 +1480,7 @@ void FTerm::setEncoding (fc::encoding enc) || term_encoding == fc::PC || term_encoding == fc::ASCII ); - // set the new Fputchar function pointer + // Set the new Fputchar function pointer switch ( term_encoding ) { case fc::UTF8: @@ -1573,7 +1567,7 @@ const FString FTerm::getAnswerbackMsg() struct timeval tv; char temp[10] = {}; - std::putchar (ENQ[0]); // send enquiry character + std::putchar (ENQ[0]); // Send enquiry character std::fflush(stdout); FD_ZERO(&ifds); @@ -1581,7 +1575,7 @@ const FString FTerm::getAnswerbackMsg() tv.tv_sec = 0; tv.tv_usec = 150000; // 150 ms - // read the answerback message + // Read the answerback message if ( select (stdin_no + 1, &ifds, 0, 0, &tv) > 0 ) if ( std::fgets (temp, sizeof(temp) - 1, stdin) != 0 ) answerback = temp; @@ -1600,7 +1594,7 @@ const FString FTerm::getSecDA() fd_set ifds; struct timeval tv; - // get the secondary device attributes + // Get the secondary device attributes putstring (SECDA); std::fflush(stdout); @@ -1609,7 +1603,7 @@ const FString FTerm::getSecDA() tv.tv_sec = 0; tv.tv_usec = 600000; // 600 ms - // read the answer + // Read the answer if ( select (stdin_no + 1, &ifds, 0, 0, &tv) == 1 ) if ( std::scanf("\033[>%10d;%10d;%10dc", &a, &b, &c) == 3 ) sec_da_str.sprintf("\033[>%d;%d;%dc", a, b, c); @@ -2060,7 +2054,7 @@ inline uChar FTerm::getAttributeMode() } //---------------------------------------------------------------------- -inline void FTerm::setAttributeMode(uChar data) +inline void FTerm::setAttributeMode (uChar data) { // Sets the attribute mode value from the vga attribute controller static const uChar attrib_mode = 0x10; @@ -2726,12 +2720,12 @@ void FTerm::init_global_values() cursor_optimisation = \ terminal_detection = true; - // assertion: programm start in cooked mode + // Assertion: programm start in cooked mode raw_mode = \ input_data_pending = \ non_blocking_stdin = false; - // init arrays with '\0' + // Init arrays with '\0' std::fill_n (exit_message, sizeof(exit_message), '\0'); if ( ! init_values.terminal_detection ) @@ -2838,6 +2832,13 @@ void FTerm::termtypeAnalysis() sun_terminal = true; } + // Kterm + if ( std::strncmp(termtype, "kterm", 5) == 0 ) + { + terminal_detection = false; + kterm_terminal = true; + } + // Linux console if ( std::strncmp(termtype, C_STR("linux"), 5) == 0 || std::strncmp(termtype, C_STR("con"), 3) == 0 ) @@ -2853,39 +2854,39 @@ void FTerm::termtypeAnalysis() } //---------------------------------------------------------------------- -bool FTerm::get256colorEnvString(colorEnv& env) +bool FTerm::get256colorEnvString() { // Enable 256 color capabilities - env.string1 = std::getenv("COLORTERM"); - env.string2 = std::getenv("VTE_VERSION"); - env.string3 = std::getenv("XTERM_VERSION"); - env.string4 = std::getenv("ROXTERM_ID"); - env.string5 = std::getenv("KONSOLE_DBUS_SESSION"); - env.string6 = std::getenv("KONSOLE_DCOP"); + color_env.string1 = std::getenv("COLORTERM"); + color_env.string2 = std::getenv("VTE_VERSION"); + color_env.string3 = std::getenv("XTERM_VERSION"); + color_env.string4 = std::getenv("ROXTERM_ID"); + color_env.string5 = std::getenv("KONSOLE_DBUS_SESSION"); + color_env.string6 = std::getenv("KONSOLE_DCOP"); - if ( env.string1 != 0 ) + if ( color_env.string1 != 0 ) return true; - if ( env.string2 != 0 ) + if ( color_env.string2 != 0 ) return true; - if ( env.string3 != 0 ) + if ( color_env.string3 != 0 ) return true; - if ( env.string4 != 0 ) + if ( color_env.string4 != 0 ) return true; - if ( env.string5 != 0 ) + if ( color_env.string5 != 0 ) return true; - if ( env.string6 != 0 ) + if ( color_env.string6 != 0 ) return true; return false; } //---------------------------------------------------------------------- -char* FTerm::termtype_256color_quirks (colorEnv& env) +char* FTerm::termtype_256color_quirks() { char* new_termtype = 0; @@ -2915,19 +2916,19 @@ char* FTerm::termtype_256color_quirks (colorEnv& env) } if ( std::strncmp(termtype, "rxvt", 4) != 0 - && env.string1 - && std::strncmp(env.string1, "rxvt-xpm", 8) == 0 ) + && color_env.string1 + && std::strncmp(color_env.string1, "rxvt-xpm", 8) == 0 ) { new_termtype = C_STR("rxvt-256color"); rxvt_terminal = true; } - if ( (env.string5 && std::strlen(env.string5) > 0) - || (env.string6 && std::strlen(env.string6) > 0) ) + if ( (color_env.string5 && std::strlen(color_env.string5) > 0) + || (color_env.string6 && std::strlen(color_env.string6) > 0) ) kde_konsole = true; - if ( (env.string1 && std::strncmp(env.string1, "gnome-terminal", 14) == 0) - || env.string2 ) + if ( (color_env.string1 && std::strncmp(color_env.string1, "gnome-terminal", 14) == 0) + || color_env.string2 ) { gnome_terminal = true; // Each gnome-terminal should be able to use 256 colors @@ -2944,16 +2945,15 @@ char* FTerm::termtype_256color_quirks (colorEnv& env) char* FTerm::init_256colorTerminal() { char* new_termtype = 0; - colorEnv env; - if ( get256colorEnvString(env) ) + if ( get256colorEnvString() ) color256 = true; else if ( std::strstr (termtype, "256color") ) color256 = true; else color256 = false; - new_termtype = termtype_256color_quirks(env); + new_termtype = termtype_256color_quirks(); #if DEBUG if ( new_termtype ) @@ -3044,11 +3044,9 @@ char* FTerm::parseAnswerbackMsg (char current_termtype[]) //---------------------------------------------------------------------- char* FTerm::parseSecDA (char current_termtype[]) { - char* new_termtype = current_termtype; - // The Linux console knows no Sec_DA if ( linux_terminal ) - return new_termtype; + return current_termtype; try { @@ -3057,170 +3055,69 @@ char* FTerm::parseSecDA (char current_termtype[]) } catch (const std::bad_alloc& ex) { - std::cerr << "not enough memory to alloc " << ex.what() << std::endl; - return new_termtype; + std::cerr << "not enough memory to alloc " << ex.what() << std::endl; + return current_termtype; } - if ( sec_da->getLength() > 5 ) + if ( sec_da->getLength() < 6 ) + return current_termtype; + + // remove the first 3 bytes ("\033[>") + FString temp = sec_da->right(sec_da->getLength() - 3); + // remove the last byte ("c") + temp.remove(temp.getLength() - 1, 1); + // split into components + FStringList sec_da_list = temp.split(';'); + + uLong num_components = sec_da_list.size(); + + // The second device attribute (SEC_DA) always has 3 parameters, + // otherwise it usually has a copy of the device attribute (primary DA) + if ( num_components < 3 ) + return current_termtype; + + const FString* sec_da_components = &sec_da_list[0]; + + if ( sec_da_components[0].isEmpty() ) + return current_termtype; + + // Read the terminal type + try { - uLong num_components; - bool sec_da_supported = false; - - // remove the first 3 bytes ("\033[>") - FString temp = sec_da->right(sec_da->getLength() - 3); - // remove the last byte ("c") - temp.remove(temp.getLength() - 1, 1); - // split into components - FStringList sec_da_list = temp.split(';'); - - num_components = sec_da_list.size(); - - // The second device attribute (SEC_DA) always has 3 parameters, - // otherwise it usually has a copy of the device attribute (primary DA) - if ( num_components == 3 ) - sec_da_supported = true; - - if ( num_components >= 2 ) - { - const FString* sec_da_components = &sec_da_list[0]; - - if ( ! sec_da_components[0].isEmpty() ) - { - int terminal_id_type, terminal_id_version; - - // Read the terminal type - try - { - terminal_id_type = sec_da_components[0].toInt(); - } - catch (const std::exception&) - { - terminal_id_type = -1; - } - - // Read the terminal (firmware) version - try - { - if ( sec_da_components[1] ) - terminal_id_version = sec_da_components[1].toInt(); - else - terminal_id_version = -1; - } - catch (const std::exception&) - { - terminal_id_version = -1; - } - - switch ( terminal_id_type ) - { - case 0: // DEC VT100 - if ( terminal_id_version == 115 ) - kde_konsole = true; - else if ( terminal_id_version == 136 ) - putty_terminal = true; // PuTTY - break; - - case 1: // DEC VT220 - if ( ! sec_da_supported ) - { - if ( terminal_id_version == 2 ) // also used by apple terminal - kterm_terminal = true; // kterm - } - else if ( terminal_id_version > 1000 ) - { - gnome_terminal = true; - // Each gnome-terminal should be able to use 256 colors - color256 = true; - new_termtype = C_STR("gnome-256color"); - gnome_terminal_id = terminal_id_version; - - // VTE 0.40.0 or higher and gnome-terminal 3.16 or higher - if ( gnome_terminal_id >= 4000 ) - decscusr_support = true; - } - break; - - case 2: // DEC VT240 - case 18: // DEC VT330 - case 19: // DEC VT340 - - case 24: // DEC VT320 -#if defined(__NetBSD__) || defined(__OpenBSD__) - if ( terminal_id_version == 20 && isWSConsConsole() ) - { - // NetBSD/OpenBSD workstation console - if ( std::strncmp(termtype, C_STR("wsvt25"), 6) == 0 ) - netbsd_terminal = true; - else if ( std::strncmp(termtype, C_STR("vt220"), 5) == 0 ) - { - openbsd_terminal = true; - new_termtype = C_STR("pccon"); - } - } - break; -#endif - case 41: // DEC VT420 - case 61: // DEC VT510 - case 64: // DEC VT520 - case 65: // DEC VT525 - break; - - case 32: // Tera Term - tera_terminal = true; - new_termtype = C_STR("teraterm"); - break; - - case 77: // mintty - mintty_terminal = true; - new_termtype = C_STR("xterm-256color"); - // switch to application escape key mode - putstring (CSI "?7727h"); - std::fflush(stdout); - break; - - case 83: // screen - screen_terminal = true; - break; - - case 82: // rxvt - rxvt_terminal = true; - force_vt100 = true; // this rxvt terminal support on utf-8 - - if ( std::strncmp(termtype, "rxvt-", 5) != 0 - && std::strncmp(termtype, "rxvt-cygwin-native", 18) == 0 ) - new_termtype = C_STR("rxvt-16color"); - else - new_termtype = termtype; - break; - - case 85: // rxvt-unicode - rxvt_terminal = true; - urxvt_terminal = true; - - if ( std::strncmp(termtype, "rxvt-", 5) != 0 ) - { - if ( color256 ) - new_termtype = C_STR("rxvt-256color"); - else - new_termtype = C_STR("rxvt"); - } - else - new_termtype = termtype; - break; - - default: - break; - } - - // Correct false assumptions - if ( gnome_terminal && terminal_id_type != 1 ) - gnome_terminal = false; - - if ( kde_konsole && terminal_id_type != 0 ) - kde_konsole = false; - } - } + secondary_da.terminal_id_type = sec_da_components[0].toInt(); } + catch (const std::exception&) + { + secondary_da.terminal_id_type = -1; + } + + // Read the terminal (firmware) version + try + { + if ( sec_da_components[1] ) + secondary_da.terminal_id_version = sec_da_components[1].toInt(); + else + secondary_da.terminal_id_version = -1; + } + catch (const std::exception&) + { + secondary_da.terminal_id_version = -1; + } + + // Read the terminal hardware option + try + { + if ( sec_da_components[2] ) + secondary_da.terminal_id_hardware = sec_da_components[2].toInt(); + else + secondary_da.terminal_id_hardware = -1; + } + catch (const std::exception&) + { + secondary_da.terminal_id_hardware = -1; + } + + char* new_termtype = secDA_Analysis(current_termtype); #if DEBUG if ( new_termtype ) @@ -3232,6 +3129,208 @@ char* FTerm::parseSecDA (char current_termtype[]) return new_termtype; } +//---------------------------------------------------------------------- +char* FTerm::secDA_Analysis (char current_termtype[]) +{ + char* new_termtype = current_termtype; + + switch ( secondary_da.terminal_id_type ) + { + case 0: // DEC VT100 + new_termtype = secDA_Analysis_0(current_termtype); + break; + + case 1: // DEC VT220 + new_termtype = secDA_Analysis_1(current_termtype); + break; + + case 2: // DEC VT240 + case 18: // DEC VT330 + case 19: // DEC VT340 + + case 24: // DEC VT320 + new_termtype = secDA_Analysis_24(current_termtype); + break; + + case 41: // DEC VT420 + case 61: // DEC VT510 + case 64: // DEC VT520 + case 65: // DEC VT525 + break; + + case 32: // Tera Term + new_termtype = secDA_Analysis_32(current_termtype); + break; + + case 77: // mintty + new_termtype = secDA_Analysis_77(current_termtype); + break; + + case 82: // rxvt + new_termtype = secDA_Analysis_82(current_termtype); + break; + + case 83: // screen + new_termtype = secDA_Analysis_83(current_termtype); + break; + + case 85: // rxvt-unicode + new_termtype = secDA_Analysis_85(current_termtype); + break; + + default: + break; + } + + // Correct false assumptions + if ( gnome_terminal && secondary_da.terminal_id_type != 1 ) + gnome_terminal = false; + + if ( kde_konsole && secondary_da.terminal_id_type != 0 ) + kde_konsole = false; + + return new_termtype; +} + +//---------------------------------------------------------------------- +inline char* FTerm::secDA_Analysis_0 (char current_termtype[]) +{ + // Terminal ID 0 - DEC VT100 + + char* new_termtype = current_termtype; + + if ( secondary_da.terminal_id_version == 115 ) + kde_konsole = true; + else if ( secondary_da.terminal_id_version == 136 ) + putty_terminal = true; // PuTTY + + return new_termtype; +} + +//---------------------------------------------------------------------- +inline char* FTerm::secDA_Analysis_1 (char current_termtype[]) +{ + // Terminal ID 1 - DEC VT220 + + char* new_termtype = current_termtype; + + if ( secondary_da.terminal_id_version > 1000 ) + { + gnome_terminal = true; + // Each gnome-terminal should be able to use 256 colors + color256 = true; + new_termtype = C_STR("gnome-256color"); + gnome_terminal_id = secondary_da.terminal_id_version; + + // VTE 0.40.0 or higher and gnome-terminal 3.16 or higher + if ( gnome_terminal_id >= 4000 ) + decscusr_support = true; + } + + return new_termtype; +} + +//---------------------------------------------------------------------- +inline char* FTerm::secDA_Analysis_24 (char current_termtype[]) +{ + // Terminal ID 24 - DEC VT320 + + char* new_termtype = current_termtype; + +#if defined(__NetBSD__) || defined(__OpenBSD__) + + if ( secondary_da.terminal_id_version == 20 && isWSConsConsole() ) + { + // NetBSD/OpenBSD workstation console + if ( std::strncmp(termtype, C_STR("wsvt25"), 6) == 0 ) + netbsd_terminal = true; + else if ( std::strncmp(termtype, C_STR("vt220"), 5) == 0 ) + { + openbsd_terminal = true; + new_termtype = C_STR("pccon"); + } + } + +#endif + + return new_termtype; +} + +//---------------------------------------------------------------------- +inline char* FTerm::secDA_Analysis_32 (char current_termtype[]) +{ + // Terminal ID 32 - Tera Term + + char* new_termtype = current_termtype; + tera_terminal = true; + new_termtype = C_STR("teraterm"); + return new_termtype; +} + +//---------------------------------------------------------------------- +inline char* FTerm::secDA_Analysis_77 (char current_termtype[]) +{ + // Terminal ID 77 - mintty + + char* new_termtype = current_termtype; + mintty_terminal = true; + new_termtype = C_STR("xterm-256color"); + // switch to application escape key mode + putstring (CSI "?7727h"); + std::fflush(stdout); + return new_termtype; +} + +//---------------------------------------------------------------------- +inline char* FTerm::secDA_Analysis_82 (char current_termtype[]) +{ + // Terminal ID 82 - rxvt + + char* new_termtype = current_termtype; + rxvt_terminal = true; + force_vt100 = true; // This rxvt terminal does not support utf-8 + + if ( std::strncmp(termtype, "rxvt-", 5) != 0 + && std::strncmp(termtype, "rxvt-cygwin-native", 18) == 0 ) + new_termtype = C_STR("rxvt-16color"); + else + new_termtype = termtype; + + return new_termtype; +} + +//---------------------------------------------------------------------- +inline char* FTerm::secDA_Analysis_83 (char current_termtype[]) +{ + // Terminal ID 83 - screen + + char* new_termtype = current_termtype; + screen_terminal = true; + return new_termtype; +} + +//---------------------------------------------------------------------- +inline char* FTerm::secDA_Analysis_85 (char current_termtype[]) +{ + // Terminal ID 85 - rxvt-unicode + + char* new_termtype = current_termtype; + rxvt_terminal = true; + urxvt_terminal = true; + + if ( std::strncmp(termtype, "rxvt-", 5) != 0 ) + { + if ( color256 ) + new_termtype = C_STR("rxvt-256color"); + else + new_termtype = C_STR("rxvt"); + } + else + new_termtype = termtype; + + return new_termtype; +} + //---------------------------------------------------------------------- void FTerm::oscPrefix() { @@ -3260,7 +3359,7 @@ void FTerm::oscPostfix() //---------------------------------------------------------------------- void FTerm::init_alt_charset() { - // read the used vt100 pairs + // Read the used vt100 pairs if ( TCAP(fc::t_acs_chars) ) { @@ -3279,7 +3378,7 @@ void FTerm::init_alt_charset() utf8_char = 1 }; - // update array 'character' with discovered vt100 pairs + // Update array 'character' with discovered vt100 pairs for (int n = 0; n <= fc::lastKeyItem; n++ ) { uChar keyChar = uChar(fc::vt100_key_to_utf8[n][vt100_key]); @@ -3313,7 +3412,7 @@ void FTerm::init_pc_charset() if ( gnome_terminal || linux_terminal ) { - // fallback if tcap "S2" is not found + // Fallback if tcap "S2" is not found if ( ! TCAP(fc::t_enter_pc_charset_mode) ) { if ( utf8_console ) @@ -3334,7 +3433,7 @@ void FTerm::init_pc_charset() reinit = true; } - // fallback if tcap "S3" is not found + // Fallback if tcap "S3" is not found if ( ! TCAP(fc::t_exit_pc_charset_mode) ) { if ( utf8_console ) @@ -4173,6 +4272,10 @@ void FTerm::init_locale() if ( tera_terminal && ! std::strcmp(nl_langinfo(CODESET), "UTF-8") ) locale_name = std::setlocale (LC_ALL, "C"); + // Kterm + if ( kterm_terminal && ! std::strcmp(nl_langinfo(CODESET), "UTF-8") ) + locale_name = std::setlocale (LC_ALL, "C"); + // Sun (color) workstation console can't show UTF-8 character if ( std::strncmp(termtype, "sun", 3) == 0 && ! std::strcmp(nl_langinfo(CODESET), "UTF-8") ) @@ -4265,6 +4368,13 @@ void FTerm::init_encoding() term_encoding = fc::VT100; Fputchar = &FTerm::putchar_ASCII; // function pointer } + else if ( FTermcap::no_utf8_acs_chars && isUTF8() + && term_encoding == fc::VT100 ) + { + ascii_console = true; + term_encoding = fc::ASCII; + Fputchar = &FTerm::putchar_ASCII; // function pointer + } // In some alternative character sets, a tab character prints a '○' // on the terminal and does not move the cursor to the next tab stop @@ -4520,7 +4630,9 @@ void FTerm::init() init_encoding(); if ( init_values.encoding != fc::UNKNOWN ) + { setEncoding(init_values.encoding); + } // Enable the terminal mouse support enableMouse(); diff --git a/src/fvterm.cpp b/src/fvterm.cpp index 6eed3b8f..0ea5ca30 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -3,7 +3,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2016-2017 Markus Gans * +* Copyright 2016-2018 Markus Gans * * * * The Final Cut is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public License * @@ -2639,12 +2639,10 @@ void FVTerm::cursorWrap() { // Wrap the cursor term_area*& vt = vterm; - int term_width = vt->width - 1; - int term_height = vt->height - 1; - if ( term_pos->getX() > term_width ) + if ( term_pos->getX() >= vt->width ) { - if ( term_pos->getY() == term_height ) + if ( term_pos->getY() == vt->height - 1 ) term_pos->x_ref()--; else { @@ -2846,6 +2844,9 @@ inline void FVTerm::charsetChanges (char_data*& next_char) { next_char->attr.bit.pc_charset = true; + if ( isPuttyTerminal() ) + return; + if ( isXTerminal() && ch_enc < 0x20 ) // Character 0x00..0x1f { if ( hasUTF8() )