Outsourcing of data from FTerm to the classes FTermios, FTermDetection and FTermcapQuirks
This commit is contained in:
parent
b619f6bec5
commit
3a8689561a
|
@ -1,3 +1,7 @@
|
|||
2017-05-02 Markus Gans <guru.mail@muenster.de>
|
||||
* Outsourcing of data from FTerm to the classes FTermios,
|
||||
FTermDetection and FTermcapQuirks
|
||||
|
||||
2017-04-19 Markus Gans <guru.mail@muenster.de>
|
||||
* Placing the terminal types in FTerm in a separate structure
|
||||
|
||||
|
|
|
@ -211,20 +211,20 @@ void debug (FApplication& TermApp)
|
|||
std::cout << "\n.------------------- debug -------------------\r\n";
|
||||
#if defined(__linux__)
|
||||
std::cout << "| Framebuffer bpp: "
|
||||
<< TermApp.framebuffer_bpp << "\r\n";
|
||||
<< TermApp.getFramebufferBpp() << "\r\n";
|
||||
#endif
|
||||
|
||||
std::cout << "| after init_256colorTerminal(): "
|
||||
<< TermApp.termtype_256color << "\r\n";
|
||||
<< TermApp.getTermType_256color() << "\r\n";
|
||||
std::cout << "| after parseAnswerbackMsg(): "
|
||||
<< TermApp.termtype_Answerback << "\r\n";
|
||||
<< TermApp.getTermType_Answerback() << "\r\n";
|
||||
std::cout << "| after parseSecDA(): "
|
||||
<< TermApp.termtype_SecDA << "\r\n";
|
||||
<< TermApp.getTermType_SecDA() << "\r\n";
|
||||
|
||||
if ( ab_s.isEmpty() )
|
||||
if ( ! ab_s.isEmpty() )
|
||||
tcapString ("| The answerback String", ab_s);
|
||||
|
||||
if ( sec_da.isEmpty() )
|
||||
if ( ! sec_da.isEmpty() )
|
||||
tcapString ("| The SecDA String", sec_da);
|
||||
|
||||
std::cout << "`------------------- debug -------------------\r\n";
|
||||
|
|
|
@ -78,8 +78,6 @@
|
|||
|
||||
#include <fcntl.h>
|
||||
#include <langinfo.h>
|
||||
#include <termios.h>
|
||||
|
||||
|
||||
#if defined(__sun) && defined(__SVR4)
|
||||
#include <termio.h>
|
||||
|
@ -105,9 +103,6 @@
|
|||
#include <ttyent.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <clocale>
|
||||
#include <cmath>
|
||||
#include <csignal>
|
||||
|
@ -125,6 +120,9 @@
|
|||
#include "final/frect.h"
|
||||
#include "final/fstring.h"
|
||||
#include "final/ftermcap.h"
|
||||
#include "final/ftermcapquirks.h"
|
||||
#include "final/ftermdetection.h"
|
||||
#include "final/ftermios.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -185,6 +183,10 @@ class FTerm
|
|||
#if DEBUG
|
||||
static const FString& getAnswerbackString();
|
||||
static const FString& getSecDAString();
|
||||
static const char* getTermType_256color();
|
||||
static const char* getTermType_Answerback();
|
||||
static const char* getTermType_SecDA();
|
||||
static int getFramebufferBpp();
|
||||
#endif
|
||||
|
||||
// Inquiries
|
||||
|
@ -210,6 +212,7 @@ class FTerm
|
|||
static bool isCygwinTerminal();
|
||||
static bool isMinttyTerm();
|
||||
static bool isLinuxTerm();
|
||||
static bool isFreeBSDTerm();
|
||||
static bool isNetBSDTerm();
|
||||
static bool isOpenBSDTerm();
|
||||
static bool isScreenTerm();
|
||||
|
@ -219,6 +222,7 @@ class FTerm
|
|||
static bool isUTF8();
|
||||
|
||||
// Mutators
|
||||
static void setTermType (char[]);
|
||||
static bool setCursorOptimisation (bool);
|
||||
static void setXTermDefaultColors (bool);
|
||||
|
||||
|
@ -234,12 +238,6 @@ class FTerm
|
|||
|
||||
static void setKeypressTimeout (const long);
|
||||
static void setDblclickInterval (const long);
|
||||
static void setTTY (const termios&);
|
||||
static void noHardwareEcho();
|
||||
static bool setRawMode (bool);
|
||||
static bool setRawMode();
|
||||
static bool unsetRawMode();
|
||||
static bool setCookedMode();
|
||||
static void disableAltScreen();
|
||||
static bool setUTF8 (bool);
|
||||
static bool setUTF8();
|
||||
|
@ -263,7 +261,6 @@ class FTerm
|
|||
static void setKDECursor (fc::kdeKonsoleCursorShape);
|
||||
static const FString* getXTermFont();
|
||||
static const FString* getXTermTitle();
|
||||
static const FString getXTermColorName (int);
|
||||
static void setXTermCursorStyle (fc::xtermCursorStyle);
|
||||
static void setXTermTitle (const FString&);
|
||||
static void setXTermForeground (const FString&);
|
||||
|
@ -295,9 +292,6 @@ class FTerm
|
|||
static bool scrollTermForward();
|
||||
static bool scrollTermReverse();
|
||||
|
||||
static const FString getAnswerbackMsg();
|
||||
static const FString getSecDA();
|
||||
|
||||
// function pointer -> static function
|
||||
static int (*Fputchar)(int);
|
||||
|
||||
|
@ -319,9 +313,6 @@ class FTerm
|
|||
static int UTF8decode (const char[]);
|
||||
|
||||
#if DEBUG
|
||||
static char termtype_256color[256];
|
||||
static char termtype_Answerback[256];
|
||||
static char termtype_SecDA[256];
|
||||
static int framebuffer_bpp;
|
||||
#endif
|
||||
|
||||
|
@ -349,8 +340,6 @@ class FTerm
|
|||
#endif
|
||||
;
|
||||
// Data Members
|
||||
static int stdin_no;
|
||||
static int stdout_no;
|
||||
static int erase_ch_length;
|
||||
static int repeat_char_length;
|
||||
static int clr_bol_length;
|
||||
|
@ -434,13 +423,6 @@ class FTerm
|
|||
|
||||
static int openConsole();
|
||||
static int closeConsole();
|
||||
static void getSystemTermType();
|
||||
static void getTTYtype();
|
||||
#if F_HAVE_GETTTYNAM
|
||||
static bool getTTYSFileEntry();
|
||||
#endif
|
||||
static void storeTTYsettings();
|
||||
static void restoreTTYsettings();
|
||||
|
||||
#if defined(__linux__)
|
||||
static int getScreenFont();
|
||||
|
@ -467,52 +449,21 @@ class FTerm
|
|||
static void initWSConsConsole();
|
||||
#endif
|
||||
|
||||
static uInt getBaudRate (const struct termios*);
|
||||
static void init_global_values();
|
||||
static void detectTerminal();
|
||||
static void termtypeAnalysis();
|
||||
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();
|
||||
static void init_pc_charset();
|
||||
static void init_cygwin_charmap();
|
||||
static void init_teraterm_charmap();
|
||||
static void init_termcaps();
|
||||
static void init_termcaps_error (int);
|
||||
static void init_termcaps_variables(char*&);
|
||||
static void init_termcaps_booleans();
|
||||
static void init_termcaps_numerics();
|
||||
static void init_termcaps_strings (char*&);
|
||||
static void init_termcaps_quirks();
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
static void init_termcaps_freebsd_quirks();
|
||||
#endif
|
||||
static void init_termcaps_cygwin_quirks();
|
||||
static void init_termcaps_linux_quirks();
|
||||
static void init_termcaps_xterm_quirks();
|
||||
static void init_termcaps_rxvt_quirks();
|
||||
static void init_termcaps_vte_quirks();
|
||||
static void init_termcaps_putty_quirks();
|
||||
static void init_termcaps_teraterm_quirks();
|
||||
static void init_termcaps_sun_quirks();
|
||||
static void init_termcaps_screen_quirks();
|
||||
static void init_termcaps_general_quirks();
|
||||
static void init_termcaps_keys (char*&);
|
||||
static void init_fixed_max_color();
|
||||
static void init_termcap();
|
||||
static void init_termcap_error (int);
|
||||
static void init_termcap_variables(char*&);
|
||||
static void init_termcap_booleans();
|
||||
static void init_termcap_numerics();
|
||||
static void init_termcap_strings (char*&);
|
||||
static void init_termcap_keys (char*&);
|
||||
static void init_OptiMove();
|
||||
static void init_OptiAttr();
|
||||
static void init_font();
|
||||
|
@ -552,9 +503,6 @@ class FTerm
|
|||
static std::map <std::string,fc::encoding>* encoding_set;
|
||||
static FTermcap::tcap_map* tcap;
|
||||
|
||||
static bool decscusr_support;
|
||||
static bool terminal_detection;
|
||||
static bool raw_mode;
|
||||
static bool input_data_pending;
|
||||
static bool non_blocking_stdin;
|
||||
static bool pc_charset_console;
|
||||
|
@ -573,14 +521,12 @@ class FTerm
|
|||
static char* locale_xterm;
|
||||
static FRect* term; // current terminal geometry
|
||||
|
||||
static int gnome_terminal_id;
|
||||
static int stdin_status_flags;
|
||||
static int fd_tty;
|
||||
static uInt baudrate;
|
||||
static long key_timeout;
|
||||
static bool resize_term;
|
||||
|
||||
static struct termios term_init;
|
||||
static fc::linuxConsoleCursorStyle linux_console_cursor_style;
|
||||
static fc::freebsdConsoleCursorStyle freebsd_console_cursor_style;
|
||||
static struct console_font_op screen_font;
|
||||
|
@ -596,37 +542,10 @@ class FTerm
|
|||
|
||||
static FOptiMove* opti_move;
|
||||
static FOptiAttr* opti_attr;
|
||||
static FTermDetection* term_detection;
|
||||
static FMouseControl* mouse;
|
||||
static const FString* xterm_font;
|
||||
static const FString* xterm_title;
|
||||
static const FString* answer_back;
|
||||
static const FString* sec_da;
|
||||
|
||||
static struct terminalType
|
||||
{
|
||||
// byte #0
|
||||
uInt8 xterm : 1;
|
||||
uInt8 ansi : 1;
|
||||
uInt8 rxvt : 1;
|
||||
uInt8 urxvt : 1;
|
||||
uInt8 mlterm : 1;
|
||||
uInt8 putty : 1;
|
||||
uInt8 kde_konsole : 1;
|
||||
uInt8 gnome_terminal : 1;
|
||||
// byte #1
|
||||
uInt8 kterm : 1;
|
||||
uInt8 tera_term : 1;
|
||||
uInt8 sun : 1;
|
||||
uInt8 cygwin : 1;
|
||||
uInt8 mintty : 1;
|
||||
uInt8 linux_con : 1;
|
||||
uInt8 netbsd_con : 1;
|
||||
uInt8 openbsd_con : 1;
|
||||
// byte #2
|
||||
uInt8 screen : 1;
|
||||
uInt8 tmux : 1;
|
||||
uInt8 : 6; // padding bits
|
||||
} terminal_type;
|
||||
|
||||
static struct colorEnv
|
||||
{
|
||||
|
@ -666,6 +585,8 @@ class FTerm
|
|||
{
|
||||
dacreg d[16];
|
||||
} color_map;
|
||||
|
||||
friend class FTermDetection;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
@ -694,21 +615,33 @@ inline int FTerm::getMaxColor()
|
|||
#if DEBUG
|
||||
//----------------------------------------------------------------------
|
||||
inline const FString& FTerm::getAnswerbackString()
|
||||
{ return ( answer_back ) ? *answer_back : fc::emptyFString::get(); }
|
||||
{ return term_detection->getAnswerbackString(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline const FString& FTerm::getSecDAString()
|
||||
{ return ( sec_da ) ? *sec_da : fc::emptyFString::get(); }
|
||||
{ return term_detection->getSecDAString(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline const char* FTerm::getTermType_256color()
|
||||
{ return term_detection->getTermType_256color(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline const char* FTerm::getTermType_Answerback()
|
||||
{ return term_detection->getTermType_Answerback(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline const char* FTerm::getTermType_SecDA()
|
||||
{ return term_detection->getTermType_SecDA(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline int FTerm::getFramebufferBpp()
|
||||
{ return framebuffer_bpp; }
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isKeypressTimeout (timeval* time)
|
||||
{ return FObject::isTimeout (time, key_timeout); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isRaw()
|
||||
{ return raw_mode; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::hasPCcharset()
|
||||
{ return pc_charset_console; }
|
||||
|
@ -731,75 +664,79 @@ inline bool FTerm::isMonochron()
|
|||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isXTerminal()
|
||||
{ return terminal_type.xterm; }
|
||||
{ return term_detection->isXTerminal(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isAnsiTerminal()
|
||||
{ return terminal_type.ansi; }
|
||||
{ return term_detection->isAnsiTerminal(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isRxvtTerminal()
|
||||
{ return terminal_type.rxvt; }
|
||||
{ return term_detection->isRxvtTerminal(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isUrxvtTerminal()
|
||||
{ return terminal_type.urxvt; }
|
||||
{ return term_detection->isUrxvtTerminal(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isMltermTerminal()
|
||||
{ return terminal_type.mlterm; }
|
||||
{ return term_detection->isMltermTerminal(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isPuttyTerminal()
|
||||
{ return terminal_type.putty; }
|
||||
{ return term_detection->isPuttyTerminal(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isKdeTerminal()
|
||||
{ return terminal_type.kde_konsole; }
|
||||
{ return term_detection->isKdeTerminal(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isGnomeTerminal()
|
||||
{ return terminal_type.gnome_terminal; }
|
||||
{ return term_detection->isGnomeTerminal(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isKtermTerminal()
|
||||
{ return terminal_type.kterm; }
|
||||
{ return term_detection->isKtermTerminal(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isTeraTerm()
|
||||
{ return terminal_type.tera_term; }
|
||||
{ return term_detection->isTeraTerm(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isSunTerminal()
|
||||
{ return terminal_type.sun; }
|
||||
{ return term_detection->isSunTerminal(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isCygwinTerminal()
|
||||
{ return terminal_type.cygwin; }
|
||||
{ return term_detection->isCygwinTerminal(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isMinttyTerm()
|
||||
{ return terminal_type.mintty; }
|
||||
{ return term_detection->isMinttyTerm(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isLinuxTerm()
|
||||
{ return terminal_type.linux_con; }
|
||||
{ return term_detection->isLinuxTerm(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isFreeBSDTerm()
|
||||
{ return term_detection->isFreeBSDTerm(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isNetBSDTerm()
|
||||
{ return terminal_type.netbsd_con; }
|
||||
{ return term_detection->isNetBSDTerm(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isOpenBSDTerm()
|
||||
{ return terminal_type.openbsd_con; }
|
||||
{ return term_detection->isOpenBSDTerm(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isScreenTerm()
|
||||
{ return terminal_type.screen; }
|
||||
{ return term_detection->isScreenTerm(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isTmuxTerm()
|
||||
{ return terminal_type.tmux; }
|
||||
{ return term_detection->isTmuxTerm(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::isInputDataPending()
|
||||
|
@ -825,18 +762,6 @@ inline void FTerm::setXTermDefaultColors (bool on)
|
|||
inline void FTerm::setKeypressTimeout (const long timeout)
|
||||
{ key_timeout = timeout; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::setRawMode()
|
||||
{ return setRawMode(true); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::unsetRawMode()
|
||||
{ return setRawMode(false); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTerm::setCookedMode()
|
||||
{ return setRawMode(false); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTerm::disableAltScreen()
|
||||
{ use_alternate_screen = false; }
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
/***********************************************************************
|
||||
* ftermcapquirks.h - Termcap quirks for some well-known terminals *
|
||||
* *
|
||||
* This file is part of the Final Cut widget toolkit *
|
||||
* *
|
||||
* Copyright 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 *
|
||||
* as published by the Free Software Foundation; either version 3 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* The Final Cut is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this program. If not, see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************/
|
||||
|
||||
/* Standalone class
|
||||
* ════════════════
|
||||
*
|
||||
* ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏
|
||||
* ▕ FTermcapQuirks ▏
|
||||
* ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏
|
||||
*/
|
||||
|
||||
#ifndef FTERMCAPQUIRKS_H
|
||||
#define FTERMCAPQUIRKS_H
|
||||
|
||||
#if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
|
||||
#error "Only <final/final.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "final/fc.h"
|
||||
#include "final/fterm.h"
|
||||
#include "final/ftermcap.h"
|
||||
#include "final/ftermdetection.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// class FTermcapsQuirks
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
|
||||
class FTermcapQuirks
|
||||
{
|
||||
public:
|
||||
// Constructors
|
||||
FTermcapQuirks();
|
||||
|
||||
// Destructor
|
||||
~FTermcapQuirks();
|
||||
|
||||
// Mutator
|
||||
static void setTerminalType (char[]);
|
||||
static void setTermcapMap (FTermcap::tcap_map*);
|
||||
static void setFTermDetection (FTermDetection*);
|
||||
|
||||
// Methods
|
||||
static void terminalFixup();
|
||||
|
||||
private:
|
||||
// Methods
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
static void init_termcap_freebsd_quirks();
|
||||
#endif
|
||||
static void init_termcap_cygwin_quirks();
|
||||
static void init_termcap_linux_quirks();
|
||||
static void init_termcap_xterm_quirks();
|
||||
static void init_termcap_rxvt_quirks();
|
||||
static void init_termcap_vte_quirks();
|
||||
static void init_termcap_putty_quirks();
|
||||
static void init_termcap_teraterm_quirks();
|
||||
static void init_termcap_sun_quirks();
|
||||
static void init_termcap_screen_quirks();
|
||||
static void init_termcap_general_quirks();
|
||||
|
||||
// Data Members
|
||||
static char termtype[256];
|
||||
static FTermcap::tcap_map* tcap;
|
||||
static FTermDetection* term_detection;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif // FTERMCAPQUIRKS_H
|
|
@ -0,0 +1,441 @@
|
|||
/***********************************************************************
|
||||
* ftermdetection.h - Detection of the terminal type *
|
||||
* *
|
||||
* This file is part of the Final Cut widget toolkit *
|
||||
* *
|
||||
* Copyright 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 *
|
||||
* as published by the Free Software Foundation; either version 3 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* The Final Cut is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this program. If not, see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
/* Standalone class
|
||||
* ════════════════
|
||||
*
|
||||
* ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏
|
||||
* ▕ FTermDetection ▏
|
||||
* ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏
|
||||
*/
|
||||
|
||||
#ifndef FTERMDETECTION_H
|
||||
#define FTERMDETECTION_H
|
||||
|
||||
#if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
|
||||
#error "Only <final/final.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <cctype>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include "final/fc.h"
|
||||
#include "final/ftermios.h"
|
||||
#include "final/ftypes.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// class FTermDetection
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
|
||||
class FTermDetection
|
||||
{
|
||||
public:
|
||||
// Typedefs
|
||||
typedef struct
|
||||
{
|
||||
// byte #0
|
||||
uInt8 xterm : 1;
|
||||
uInt8 ansi : 1;
|
||||
uInt8 rxvt : 1;
|
||||
uInt8 urxvt : 1;
|
||||
uInt8 mlterm : 1;
|
||||
uInt8 putty : 1;
|
||||
uInt8 kde_konsole : 1;
|
||||
uInt8 gnome_terminal : 1;
|
||||
// byte #1
|
||||
uInt8 kterm : 1;
|
||||
uInt8 tera_term : 1;
|
||||
uInt8 cygwin : 1;
|
||||
uInt8 mintty : 1;
|
||||
uInt8 linux_con : 1;
|
||||
uInt8 freebsd_con : 1;
|
||||
uInt8 netbsd_con : 1;
|
||||
uInt8 openbsd_con : 1;
|
||||
// byte #2
|
||||
uInt8 sun_con : 1;
|
||||
uInt8 screen : 1;
|
||||
uInt8 tmux : 1;
|
||||
uInt8 : 5; // padding bits
|
||||
} terminalType;
|
||||
|
||||
// Constructors
|
||||
FTermDetection();
|
||||
|
||||
// Destructor
|
||||
~FTermDetection();
|
||||
|
||||
// Accessor
|
||||
static char* getTermType();
|
||||
static char* getTermFileName();
|
||||
static int getGnomeTerminalID();
|
||||
terminalType& getTermTypeStruct();
|
||||
|
||||
#if DEBUG
|
||||
static const FString& getAnswerbackString();
|
||||
static const FString& getSecDAString();
|
||||
static const char* getTermType_256color();
|
||||
static const char* getTermType_Answerback();
|
||||
static const char* getTermType_SecDA();
|
||||
#endif
|
||||
|
||||
// Inquiries
|
||||
static bool isXTerminal();
|
||||
static bool isAnsiTerminal();
|
||||
static bool isRxvtTerminal();
|
||||
static bool isUrxvtTerminal();
|
||||
static bool isMltermTerminal();
|
||||
static bool isPuttyTerminal();
|
||||
static bool isKdeTerminal();
|
||||
static bool isGnomeTerminal();
|
||||
static bool isKtermTerminal();
|
||||
static bool isTeraTerm();
|
||||
static bool isSunTerminal();
|
||||
static bool isCygwinTerminal();
|
||||
static bool isMinttyTerm();
|
||||
static bool isLinuxTerm();
|
||||
static bool isFreeBSDTerm();
|
||||
static bool isNetBSDTerm();
|
||||
static bool isOpenBSDTerm();
|
||||
static bool isScreenTerm();
|
||||
static bool isTmuxTerm();
|
||||
static bool hasTerminalDetection();
|
||||
static bool hasSetCursorStyleSupport();
|
||||
|
||||
// Mutators
|
||||
static void setXTerminal (bool);
|
||||
static void setAnsiTerminal (bool);
|
||||
static void setRxvtTerminal (bool);
|
||||
static void setUrxvtTerminal (bool);
|
||||
static void setMltermTerminal (bool);
|
||||
static void setPuttyTerminal (bool);
|
||||
static void setKdeTerminal (bool);
|
||||
static void setGnomeTerminal (bool);
|
||||
static void setKtermTerminal (bool);
|
||||
static void setTeraTerm (bool);
|
||||
static void setSunTerminal (bool);
|
||||
static void setCygwinTerminal (bool);
|
||||
static void setMinttyTerm (bool);
|
||||
static void setLinuxTerm (bool);
|
||||
static void setFreeBSDTerm (bool);
|
||||
static void setNetBSDTerm (bool);
|
||||
static void setOpenBSDTerm (bool);
|
||||
static void setScreenTerm (bool);
|
||||
static void setTmuxTerm (bool);
|
||||
static void setTerminalDetection (bool);
|
||||
static void setTermFileName (char[]);
|
||||
|
||||
// Methods
|
||||
static void detect();
|
||||
|
||||
// Data Members
|
||||
#if DEBUG
|
||||
static char termtype_256color[256];
|
||||
static char termtype_Answerback[256];
|
||||
static char termtype_SecDA[256];
|
||||
#endif
|
||||
|
||||
private:
|
||||
// Methods
|
||||
static void getSystemTermType();
|
||||
static void getTTYtype();
|
||||
#if F_HAVE_GETTTYNAM
|
||||
static bool getTTYSFileEntry();
|
||||
#endif
|
||||
static void termtypeAnalysis();
|
||||
static void detectTerminal();
|
||||
static char* init_256colorTerminal();
|
||||
static bool get256colorEnvString();
|
||||
static char* termtype_256color_quirks();
|
||||
static char* determineMaxColor (char[]);
|
||||
static const FString getXTermColorName (int);
|
||||
static char* parseAnswerbackMsg (char[]);
|
||||
static const FString getAnswerbackMsg();
|
||||
static char* parseSecDA (char[]);
|
||||
static const FString getSecDA();
|
||||
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[]);
|
||||
|
||||
// Data Members
|
||||
static char termtype[256];
|
||||
static char termfilename[256];
|
||||
static bool decscusr_support;
|
||||
static bool terminal_detection;
|
||||
static bool color256;
|
||||
static int gnome_terminal_id;
|
||||
static const FString* answer_back;
|
||||
static const FString* sec_da;
|
||||
static terminalType terminal_type;
|
||||
|
||||
static struct colorEnv
|
||||
{
|
||||
void setDefault()
|
||||
{
|
||||
string1 = 0;
|
||||
string2 = 0;
|
||||
string3 = 0;
|
||||
string4 = 0;
|
||||
string5 = 0;
|
||||
string6 = 0;
|
||||
}
|
||||
|
||||
char* string1;
|
||||
char* string2;
|
||||
char* string3;
|
||||
char* string4;
|
||||
char* string5;
|
||||
char* string6;
|
||||
} color_env;
|
||||
|
||||
static struct secondaryDA
|
||||
{
|
||||
void setDefault()
|
||||
{
|
||||
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;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
// FTermDetection inline functions
|
||||
//----------------------------------------------------------------------
|
||||
inline char* FTermDetection::getTermType()
|
||||
{ return termtype; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline char* FTermDetection::getTermFileName()
|
||||
{ return termfilename; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline int FTermDetection::getGnomeTerminalID()
|
||||
{ return gnome_terminal_id; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline FTermDetection::terminalType& FTermDetection::getTermTypeStruct()
|
||||
{ return terminal_type; }
|
||||
|
||||
#if DEBUG
|
||||
//----------------------------------------------------------------------
|
||||
inline const FString& FTermDetection::getAnswerbackString()
|
||||
{ return ( answer_back ) ? *answer_back : fc::emptyFString::get(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline const FString& FTermDetection::getSecDAString()
|
||||
{ return ( sec_da ) ? *sec_da : fc::emptyFString::get(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline const char* FTermDetection::getTermType_256color()
|
||||
{ return termtype_256color; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline const char* FTermDetection::getTermType_Answerback()
|
||||
{ return termtype_Answerback; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline const char* FTermDetection::getTermType_SecDA()
|
||||
{ return termtype_SecDA; }
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::hasSetCursorStyleSupport()
|
||||
{ return decscusr_support; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::isXTerminal()
|
||||
{ return terminal_type.xterm; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::isAnsiTerminal()
|
||||
{ return terminal_type.ansi; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::isRxvtTerminal()
|
||||
{ return terminal_type.rxvt; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::isUrxvtTerminal()
|
||||
{ return terminal_type.urxvt; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::isMltermTerminal()
|
||||
{ return terminal_type.mlterm; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::isPuttyTerminal()
|
||||
{ return terminal_type.putty; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::isKdeTerminal()
|
||||
{ return terminal_type.kde_konsole; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::isGnomeTerminal()
|
||||
{ return terminal_type.gnome_terminal; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::isKtermTerminal()
|
||||
{ return terminal_type.kterm; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::isTeraTerm()
|
||||
{ return terminal_type.tera_term; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::isSunTerminal()
|
||||
{ return terminal_type.sun_con; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::isCygwinTerminal()
|
||||
{ return terminal_type.cygwin; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::isMinttyTerm()
|
||||
{ return terminal_type.mintty; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::isLinuxTerm()
|
||||
{ return terminal_type.linux_con; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::isFreeBSDTerm()
|
||||
{ return terminal_type.freebsd_con; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::isNetBSDTerm()
|
||||
{ return terminal_type.netbsd_con; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::isOpenBSDTerm()
|
||||
{ return terminal_type.openbsd_con; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::isScreenTerm()
|
||||
{ return terminal_type.screen; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::isTmuxTerm()
|
||||
{ return terminal_type.tmux; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermDetection::hasTerminalDetection()
|
||||
{ return terminal_detection; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermDetection::setXTerminal (bool on)
|
||||
{ terminal_type.xterm = on; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermDetection::setAnsiTerminal (bool on)
|
||||
{ terminal_type.ansi = on; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermDetection::setRxvtTerminal (bool on)
|
||||
{ terminal_type.rxvt = on; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermDetection::setUrxvtTerminal (bool on)
|
||||
{ terminal_type.urxvt = on; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermDetection::setMltermTerminal (bool on)
|
||||
{ terminal_type.mlterm = on; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermDetection::setPuttyTerminal (bool on)
|
||||
{ terminal_type.putty = on; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermDetection::setKdeTerminal (bool on)
|
||||
{ terminal_type.kde_konsole = on; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermDetection::setGnomeTerminal (bool on)
|
||||
{ terminal_type.gnome_terminal = on; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermDetection::setKtermTerminal (bool on)
|
||||
{ terminal_type.kterm = on; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermDetection::setTeraTerm (bool on)
|
||||
{ terminal_type.tera_term = on; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermDetection::setSunTerminal (bool on)
|
||||
{ terminal_type.sun_con = on; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermDetection::setCygwinTerminal (bool on)
|
||||
{ terminal_type.cygwin = on; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermDetection::setMinttyTerm (bool on)
|
||||
{ terminal_type.mintty = on; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermDetection::setLinuxTerm (bool on)
|
||||
{ terminal_type.linux_con = on; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermDetection::setFreeBSDTerm (bool on)
|
||||
{ terminal_type.freebsd_con = on; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermDetection::setNetBSDTerm (bool on)
|
||||
{ terminal_type.netbsd_con = on; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermDetection::setOpenBSDTerm (bool on)
|
||||
{ terminal_type.openbsd_con = on; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermDetection::setScreenTerm (bool on)
|
||||
{ terminal_type.screen = on; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermDetection::setTmuxTerm (bool on)
|
||||
{ terminal_type.tmux = on; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermDetection::setTerminalDetection (bool on)
|
||||
{ terminal_detection = on; }
|
||||
|
||||
#endif // FTERMDETECTION_H
|
|
@ -0,0 +1,119 @@
|
|||
/***********************************************************************
|
||||
* ftermios.h - Provides access to POSIX tty I/O control *
|
||||
* *
|
||||
* This file is part of the Final Cut widget toolkit *
|
||||
* *
|
||||
* Copyright 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 *
|
||||
* as published by the Free Software Foundation; either version 3 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* The Final Cut is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this program. If not, see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************/
|
||||
|
||||
/* Standalone class
|
||||
* ════════════════
|
||||
*
|
||||
* ▕▔▔▔▔▔▔▔▔▔▔▏
|
||||
* ▕ FTermios ▏
|
||||
* ▕▁▁▁▁▁▁▁▁▁▁▏
|
||||
*/
|
||||
|
||||
#ifndef FTERMIOS_H
|
||||
#define FTERMIOS_H
|
||||
|
||||
#if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
|
||||
#error "Only <final/final.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "final/fterm.h"
|
||||
#include "final/ftypes.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// class FTermios
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
|
||||
class FTermios
|
||||
{
|
||||
public:
|
||||
// Constructors
|
||||
FTermios();
|
||||
|
||||
// Destructor
|
||||
~FTermios();
|
||||
|
||||
// Accessors
|
||||
static termios getTTY();
|
||||
static int getStdIn();
|
||||
static int getStdOut();
|
||||
|
||||
// Inquiries
|
||||
static bool isRaw();
|
||||
|
||||
// Methods
|
||||
static void init();
|
||||
static void setTTY (const termios&);
|
||||
static void storeTTYsettings();
|
||||
static void restoreTTYsettings();
|
||||
static void setHardwareEcho();
|
||||
static void unsetHardwareEcho();
|
||||
static void setCaptureSendCharacters();
|
||||
static void unsetCaptureSendCharacters();
|
||||
static bool setRawMode (bool);
|
||||
static bool setRawMode();
|
||||
static bool unsetRawMode();
|
||||
static bool setCookedMode();
|
||||
static uInt getBaudRate();
|
||||
|
||||
private:
|
||||
// Data Members
|
||||
static int stdin_no;
|
||||
static int stdout_no;
|
||||
static bool raw_mode;
|
||||
static struct termios term_init;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
// FTermios inline functions
|
||||
//----------------------------------------------------------------------
|
||||
inline int FTermios::getStdIn()
|
||||
{ return stdin_no; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline int FTermios::getStdOut()
|
||||
{ return stdout_no; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermios::isRaw()
|
||||
{ return raw_mode; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermios::setRawMode()
|
||||
{ return setRawMode(true); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermios::unsetRawMode()
|
||||
{ return setRawMode(false); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermios::setCookedMode()
|
||||
{ return setRawMode(false); }
|
||||
|
||||
|
||||
#endif // FTERMIOS_H
|
|
@ -40,6 +40,9 @@ libfinal_la_SOURCES = \
|
|||
ffiledialog.cpp \
|
||||
ftextview.cpp \
|
||||
fstatusbar.cpp \
|
||||
ftermcapquirks.cpp \
|
||||
ftermdetection.cpp \
|
||||
ftermios.cpp \
|
||||
fterm.cpp \
|
||||
fvterm.cpp \
|
||||
fevent.cpp \
|
||||
|
@ -67,6 +70,7 @@ finalcutinclude_HEADERS = \
|
|||
../include/final/fdialog.h \
|
||||
../include/final/fc.h \
|
||||
../include/final/ftypes.h \
|
||||
../include/final/emptyfstring.h \
|
||||
../include/final/fevent.h \
|
||||
../include/final/ffiledialog.h \
|
||||
../include/final/final.h \
|
||||
|
@ -99,6 +103,9 @@ finalcutinclude_HEADERS = \
|
|||
../include/final/fstring.h \
|
||||
../include/final/ftcap_map.h \
|
||||
../include/final/ftermcap.h \
|
||||
../include/final/ftermcapquirks.h \
|
||||
../include/final/ftermdetection.h \
|
||||
../include/final/ftermios.h \
|
||||
../include/final/fterm.h \
|
||||
../include/final/fvterm.h \
|
||||
../include/final/ftextview.h \
|
||||
|
|
|
@ -44,6 +44,9 @@ INCLUDE_HEADERS = \
|
|||
fstring.h \
|
||||
ftermcap.h \
|
||||
fterm.h \
|
||||
ftermios.h \
|
||||
ftermdetection.h \
|
||||
ftermcapquirks.h \
|
||||
fvterm.h \
|
||||
ftextview.h \
|
||||
ftogglebutton.h \
|
||||
|
@ -95,6 +98,9 @@ OBJS = \
|
|||
ftextview.o \
|
||||
fstatusbar.o \
|
||||
fterm.o \
|
||||
ftermios.o \
|
||||
ftermdetection.o \
|
||||
ftermcapquirks.o \
|
||||
fvterm.o \
|
||||
fevent.o \
|
||||
foptiattr.o \
|
||||
|
|
|
@ -44,6 +44,9 @@ INCLUDE_HEADERS = \
|
|||
fstring.h \
|
||||
ftermcap.h \
|
||||
fterm.h \
|
||||
ftermios.h \
|
||||
ftermdetection.h \
|
||||
ftermcapquirks.h \
|
||||
fvterm.h \
|
||||
ftextview.h \
|
||||
ftogglebutton.h \
|
||||
|
@ -95,6 +98,9 @@ OBJS = \
|
|||
ftextview.o \
|
||||
fstatusbar.o \
|
||||
fterm.o \
|
||||
ftermios.o \
|
||||
ftermdetection.o \
|
||||
ftermcapquirks.o \
|
||||
fvterm.o \
|
||||
fevent.o \
|
||||
foptiattr.o \
|
||||
|
|
|
@ -136,9 +136,10 @@ am_libfinal_la_OBJECTS = fstring.lo fpoint.lo frect.lo fscrollbar.lo \
|
|||
fdialoglistmenu.lo fmenubar.lo fmenuitem.lo fradiomenuitem.lo \
|
||||
fcheckmenuitem.lo fmenulist.lo fdialog.lo fscrollview.lo \
|
||||
fwindow.lo fmessagebox.lo ftooltip.lo ffiledialog.lo \
|
||||
ftextview.lo fstatusbar.lo fterm.lo fvterm.lo fevent.lo \
|
||||
foptiattr.lo foptimove.lo ftermbuffer.lo fapplication.lo \
|
||||
fcolorpalette.lo fwidgetcolors.lo fwidget.lo fobject.lo
|
||||
ftextview.lo fstatusbar.lo ftermcapquirks.lo ftermdetection.lo \
|
||||
ftermios.lo fterm.lo fvterm.lo fevent.lo foptiattr.lo \
|
||||
foptimove.lo ftermbuffer.lo fapplication.lo fcolorpalette.lo \
|
||||
fwidgetcolors.lo fwidget.lo fobject.lo
|
||||
libfinal_la_OBJECTS = $(am_libfinal_la_OBJECTS)
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||
|
@ -412,6 +413,9 @@ libfinal_la_SOURCES = \
|
|||
ffiledialog.cpp \
|
||||
ftextview.cpp \
|
||||
fstatusbar.cpp \
|
||||
ftermcapquirks.cpp \
|
||||
ftermdetection.cpp \
|
||||
ftermios.cpp \
|
||||
fterm.cpp \
|
||||
fvterm.cpp \
|
||||
fevent.cpp \
|
||||
|
@ -437,6 +441,7 @@ finalcutinclude_HEADERS = \
|
|||
../include/final/fdialog.h \
|
||||
../include/final/fc.h \
|
||||
../include/final/ftypes.h \
|
||||
../include/final/emptyfstring.h \
|
||||
../include/final/fevent.h \
|
||||
../include/final/ffiledialog.h \
|
||||
../include/final/final.h \
|
||||
|
@ -469,6 +474,9 @@ finalcutinclude_HEADERS = \
|
|||
../include/final/fstring.h \
|
||||
../include/final/ftcap_map.h \
|
||||
../include/final/ftermcap.h \
|
||||
../include/final/ftermcapquirks.h \
|
||||
../include/final/ftermdetection.h \
|
||||
../include/final/ftermios.h \
|
||||
../include/final/fterm.h \
|
||||
../include/final/fvterm.h \
|
||||
../include/final/ftextview.h \
|
||||
|
@ -592,6 +600,9 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fswitch.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fterm.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftermbuffer.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftermcapquirks.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftermdetection.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftermios.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftextview.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftogglebutton.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftooltip.Plo@am__quote@
|
||||
|
|
|
@ -369,7 +369,7 @@ void FApplication::init (long key_time, long dblclick_time)
|
|||
|
||||
// Set stdin number for a gpm-mouse
|
||||
if ( mouse )
|
||||
mouse->setStdinNo (stdin_no);
|
||||
mouse->setStdinNo (FTermios::getStdIn());
|
||||
|
||||
// Set the default double click interval
|
||||
if ( mouse )
|
||||
|
@ -465,6 +465,7 @@ inline bool FApplication::KeyPressed()
|
|||
register int result;
|
||||
fd_set ifds;
|
||||
struct timeval tv;
|
||||
int stdin_no = FTermios::getStdIn();
|
||||
|
||||
FD_ZERO(&ifds);
|
||||
FD_SET(stdin_no, &ifds);
|
||||
|
@ -483,7 +484,7 @@ inline ssize_t FApplication::readKey()
|
|||
{
|
||||
register ssize_t bytes;
|
||||
setNonBlockingInput();
|
||||
bytes = read(stdin_no, &k_buf, sizeof(k_buf) - 1);
|
||||
bytes = read(FTermios::getStdIn(), &k_buf, sizeof(k_buf) - 1);
|
||||
unsetNonBlockingInput();
|
||||
return bytes;
|
||||
}
|
||||
|
|
1596
src/fterm.cpp
1596
src/fterm.cpp
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,500 @@
|
|||
/***********************************************************************
|
||||
* ftermcapquirks.cpp - Termcap quirks for some well-known terminals *
|
||||
* *
|
||||
* This file is part of the Final Cut widget toolkit *
|
||||
* *
|
||||
* Copyright 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 *
|
||||
* as published by the Free Software Foundation; either version 3 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* The Final Cut is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this program. If not, see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************/
|
||||
|
||||
#include "final/ftermcapquirks.h"
|
||||
|
||||
// static class attributes
|
||||
char FTermcapQuirks::termtype[256] = {};
|
||||
FTermcap::tcap_map* FTermcapQuirks::tcap = 0;
|
||||
FTermDetection* FTermcapQuirks::term_detection = 0;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// class FTermcapQuirks
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// constructors and destructor
|
||||
//----------------------------------------------------------------------
|
||||
FTermcapQuirks::FTermcapQuirks()
|
||||
{ }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
FTermcapQuirks::~FTermcapQuirks() // destructor
|
||||
{ }
|
||||
|
||||
|
||||
// public methods of FTermcapQuirks
|
||||
//----------------------------------------------------------------------
|
||||
void FTermcapQuirks::setTerminalType (char tt[])
|
||||
{
|
||||
std::strncpy (termtype, tt, sizeof(termtype) - 1);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermcapQuirks::setTermcapMap (FTermcap::tcap_map* tc)
|
||||
{
|
||||
tcap = tc;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermcapQuirks::setFTermDetection (FTermDetection* td)
|
||||
{
|
||||
term_detection = td;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// private methods of FTermcapQuirks
|
||||
//----------------------------------------------------------------------
|
||||
void FTermcapQuirks::terminalFixup()
|
||||
{
|
||||
FTermDetection* td = term_detection;
|
||||
|
||||
if ( td->isCygwinTerminal() )
|
||||
{
|
||||
init_termcap_cygwin_quirks();
|
||||
}
|
||||
else if ( td->isLinuxTerm() )
|
||||
{
|
||||
init_termcap_linux_quirks();
|
||||
}
|
||||
else if ( td->isRxvtTerminal() )
|
||||
{
|
||||
init_termcap_rxvt_quirks();
|
||||
}
|
||||
else if ( td->isGnomeTerminal() )
|
||||
{
|
||||
init_termcap_vte_quirks();
|
||||
}
|
||||
else if ( td->isTeraTerm() )
|
||||
{
|
||||
init_termcap_teraterm_quirks();
|
||||
}
|
||||
else if ( td->isSunTerminal() )
|
||||
{
|
||||
init_termcap_sun_quirks();
|
||||
}
|
||||
else if ( td->isPuttyTerminal() )
|
||||
{
|
||||
init_termcap_putty_quirks();
|
||||
}
|
||||
else if ( td->isScreenTerm() )
|
||||
{
|
||||
init_termcap_screen_quirks();
|
||||
}
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
else if ( td->isFreeBSDTerm() )
|
||||
{
|
||||
init_termcap_freebsd_quirks();
|
||||
}
|
||||
#endif
|
||||
|
||||
// xterm and compatible terminals
|
||||
if ( td->isXTerminal() && ! td->isPuttyTerminal() )
|
||||
init_termcap_xterm_quirks();
|
||||
|
||||
// Fixes general quirks
|
||||
init_termcap_general_quirks();
|
||||
}
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
//----------------------------------------------------------------------
|
||||
void FTermcapQuirks::init_termcap_freebsd_quirks()
|
||||
{
|
||||
// FreeBSD console fixes
|
||||
|
||||
TCAP(fc::t_acs_chars) = \
|
||||
C_STR("-\036.\0370\333"
|
||||
"a\260f\370g\361"
|
||||
"h\261j\331k\277"
|
||||
"l\332m\300n\305"
|
||||
"q\304t\303u\264"
|
||||
"v\301w\302x\263"
|
||||
"y\363z\362~\371");
|
||||
|
||||
TCAP(fc::t_set_attributes) = \
|
||||
C_STR(CSI "0"
|
||||
"%?%p1%p6%|%t;1%;"
|
||||
"%?%p2%t;4%;"
|
||||
"%?%p1%p3%|%t;7%;"
|
||||
"%?%p4%t;5%;m"
|
||||
"%?%p9%t\016%e\017%;");
|
||||
|
||||
FTermcap::attr_without_color = 18;
|
||||
}
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermcapQuirks::init_termcap_cygwin_quirks()
|
||||
{
|
||||
// Set invisible cursor for cygwin terminal
|
||||
if ( ! TCAP(fc::t_cursor_invisible) )
|
||||
TCAP(fc::t_cursor_invisible) = \
|
||||
C_STR(CSI "?25l");
|
||||
|
||||
// Set visible cursor for cygwin terminal
|
||||
if ( ! TCAP(fc::t_cursor_visible) )
|
||||
TCAP(fc::t_cursor_visible) = \
|
||||
C_STR(CSI "?25h");
|
||||
|
||||
// Set ansi blink for cygwin terminal
|
||||
if ( ! TCAP(fc::t_enter_blink_mode) )
|
||||
TCAP(fc::t_enter_blink_mode) = \
|
||||
C_STR(CSI "5m");
|
||||
|
||||
// Set enable alternate character set for cygwin terminal
|
||||
if ( ! TCAP(fc::t_enable_acs) )
|
||||
TCAP(fc::t_enable_acs) = \
|
||||
C_STR(ESC "(B" ESC ")0");
|
||||
|
||||
// Set background color erase for cygwin terminal
|
||||
FTermcap::background_color_erase = true;
|
||||
|
||||
// Include the Linux console quirks
|
||||
init_termcap_linux_quirks();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermcapQuirks::init_termcap_linux_quirks()
|
||||
{
|
||||
/* Same settings are used by cygwin */
|
||||
|
||||
// Set ansi foreground and background color
|
||||
if ( FTermcap::max_color > 8 )
|
||||
{
|
||||
TCAP(fc::t_set_a_foreground) = \
|
||||
C_STR(CSI "3%p1%{8}%m%d%?%p1%{7}%>%t;1%e;22%;m");
|
||||
TCAP(fc::t_set_a_background) = \
|
||||
C_STR(CSI "4%p1%{8}%m%d%?%p1%{7}%>%t;5%e;25%;m");
|
||||
// Avoid underline, blink and dim mode
|
||||
FTermcap::attr_without_color = 26;
|
||||
}
|
||||
else
|
||||
{
|
||||
TCAP(fc::t_set_a_foreground) = \
|
||||
C_STR(CSI "3%p1%dm");
|
||||
TCAP(fc::t_set_a_background) = \
|
||||
C_STR(CSI "4%p1%dm");
|
||||
// Avoid underline and dim mode
|
||||
FTermcap::attr_without_color = 18;
|
||||
}
|
||||
|
||||
// Set select graphic rendition attributes
|
||||
TCAP(fc::t_set_attributes) = \
|
||||
C_STR(CSI "0"
|
||||
"%?%p6%|%t;1%;"
|
||||
"%?%p1%p3%|%t;7%;"
|
||||
"%?%p4%t;5%;m"
|
||||
"%?%p9%t\016%e\017%;");
|
||||
|
||||
TCAP(fc::t_enter_alt_charset_mode) = C_STR("\016");
|
||||
TCAP(fc::t_exit_alt_charset_mode) = C_STR("\017");
|
||||
TCAP(fc::t_exit_attribute_mode) = C_STR(CSI "0m\017");
|
||||
TCAP(fc::t_exit_bold_mode) = C_STR(CSI "22m");
|
||||
TCAP(fc::t_exit_blink_mode) = C_STR(CSI "25m");
|
||||
TCAP(fc::t_exit_reverse_mode) = C_STR(CSI "27m");
|
||||
TCAP(fc::t_exit_secure_mode) = 0;
|
||||
TCAP(fc::t_exit_protected_mode) = 0;
|
||||
TCAP(fc::t_exit_crossed_out_mode) = 0;
|
||||
TCAP(fc::t_orig_pair) = C_STR(CSI "39;49;25m");
|
||||
|
||||
// Avoid underline and dim mode
|
||||
TCAP(fc::t_enter_dim_mode) = 0;
|
||||
TCAP(fc::t_exit_dim_mode) = 0;
|
||||
TCAP(fc::t_enter_underline_mode) = 0;
|
||||
TCAP(fc::t_exit_underline_mode) = 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermcapQuirks::init_termcap_xterm_quirks()
|
||||
{
|
||||
// Fallback if "Ic" is not found
|
||||
if ( ! TCAP(fc::t_initialize_color) )
|
||||
{
|
||||
TCAP(fc::t_initialize_color) = \
|
||||
C_STR(OSC "4;%p1%d;rgb:"
|
||||
"%p2%{255}%*%{1000}%/%2.2X/"
|
||||
"%p3%{255}%*%{1000}%/%2.2X/"
|
||||
"%p4%{255}%*%{1000}%/%2.2X" ESC "\\");
|
||||
}
|
||||
|
||||
// Fallback if "vi" is not found
|
||||
if ( ! TCAP(fc::t_cursor_invisible) )
|
||||
TCAP(fc::t_cursor_invisible) = \
|
||||
C_STR(CSI "?25l");
|
||||
|
||||
// Fallback if "ve" is not found
|
||||
if ( ! TCAP(fc::t_cursor_normal) )
|
||||
TCAP(fc::t_cursor_normal) = \
|
||||
C_STR(CSI "?12l" CSI "?25h");
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermcapQuirks::init_termcap_rxvt_quirks()
|
||||
{
|
||||
// Set enter/exit alternative charset mode for rxvt terminal
|
||||
if ( std::strncmp(termtype, "rxvt-16color", 12) == 0 )
|
||||
{
|
||||
TCAP(fc::t_enter_alt_charset_mode) = \
|
||||
C_STR(ESC "(0");
|
||||
TCAP(fc::t_exit_alt_charset_mode) = \
|
||||
C_STR(ESC "(B");
|
||||
}
|
||||
|
||||
// Set ansi foreground and background color
|
||||
if ( ! term_detection->isUrxvtTerminal() )
|
||||
{
|
||||
TCAP(fc::t_set_a_foreground) = \
|
||||
C_STR(CSI "%?%p1%{8}%<%t%p1%{30}%+%e%p1%'R'%+%;%dm");
|
||||
TCAP(fc::t_set_a_background) = \
|
||||
C_STR(CSI "%?%p1%{8}%<%t%p1%'('%+%e%p1%{92}%+%;%dm");
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermcapQuirks::init_termcap_vte_quirks()
|
||||
{
|
||||
// gnome-terminal has NC=16 however, it can use the dim attribute
|
||||
FTermcap::attr_without_color = 0;
|
||||
|
||||
// set exit underline for gnome terminal
|
||||
TCAP(fc::t_exit_underline_mode) = \
|
||||
C_STR(CSI "24m");
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermcapQuirks::init_termcap_putty_quirks()
|
||||
{
|
||||
FTermcap::background_color_erase = true;
|
||||
FTermcap::osc_support = true;
|
||||
|
||||
// PuTTY has NC=22 however, it can show underline and reverse
|
||||
// and since version 0.71 is the dim attribute is also supported
|
||||
FTermcap::attr_without_color = 0;
|
||||
|
||||
// Set ansi foreground and background color
|
||||
TCAP(fc::t_set_a_foreground) = \
|
||||
C_STR(CSI "%?%p1%{8}%<"
|
||||
"%t3%p1%d"
|
||||
"%e%p1%{16}%<"
|
||||
"%t9%p1%{8}%-%d"
|
||||
"%e38;5;%p1%d%;m");
|
||||
|
||||
TCAP(fc::t_set_a_background) = \
|
||||
C_STR(CSI "%?%p1%{8}%<"
|
||||
"%t4%p1%d"
|
||||
"%e%p1%{16}%<"
|
||||
"%t10%p1%{8}%-%d"
|
||||
"%e48;5;%p1%d%;m");
|
||||
|
||||
TCAP(fc::t_set_attributes) = \
|
||||
C_STR(CSI "0"
|
||||
"%?%p1%p6%|%t;1%;"
|
||||
"%?%p5%t;2%;" // since putty 0.71
|
||||
"%?%p2%t;4%;"
|
||||
"%?%p1%p3%|%t;7%;"
|
||||
"%?%p4%t;5%;m"
|
||||
"%?%p9%t\016%e\017%;");
|
||||
// PuTTY 0.71 or higher
|
||||
TCAP(fc::t_enter_dim_mode) = \
|
||||
C_STR(CSI "2m");
|
||||
|
||||
// PuTTY 0.71 or higher
|
||||
TCAP(fc::t_exit_dim_mode) = \
|
||||
C_STR(CSI "22m");
|
||||
|
||||
if ( ! TCAP(fc::t_clr_bol) )
|
||||
TCAP(fc::t_clr_bol) = \
|
||||
C_STR(CSI "1K");
|
||||
|
||||
if ( ! TCAP(fc::t_orig_pair) )
|
||||
TCAP(fc::t_orig_pair) = \
|
||||
C_STR(CSI "39;49m");
|
||||
|
||||
if ( ! TCAP(fc::t_orig_colors) )
|
||||
TCAP(fc::t_orig_colors) = \
|
||||
C_STR(OSC "R");
|
||||
|
||||
if ( ! TCAP(fc::t_column_address) )
|
||||
TCAP(fc::t_column_address) = \
|
||||
C_STR(CSI "%i%p1%dG");
|
||||
|
||||
if ( ! TCAP(fc::t_row_address) )
|
||||
TCAP(fc::t_row_address) = \
|
||||
C_STR(CSI "%i%p1%dd");
|
||||
|
||||
if ( ! TCAP(fc::t_enable_acs) )
|
||||
TCAP(fc::t_enable_acs) = \
|
||||
C_STR(ESC "(B" ESC ")0");
|
||||
|
||||
if ( ! TCAP(fc::t_enter_am_mode) )
|
||||
TCAP(fc::t_enter_am_mode) = \
|
||||
C_STR(CSI "?7h");
|
||||
|
||||
if ( ! TCAP(fc::t_exit_am_mode) )
|
||||
TCAP(fc::t_exit_am_mode) = \
|
||||
C_STR(CSI "?7l");
|
||||
|
||||
if ( ! TCAP(fc::t_enter_pc_charset_mode) )
|
||||
TCAP(fc::t_enter_pc_charset_mode) = \
|
||||
C_STR(CSI "11m");
|
||||
|
||||
if ( ! TCAP(fc::t_exit_pc_charset_mode) )
|
||||
TCAP(fc::t_exit_pc_charset_mode) = \
|
||||
C_STR(CSI "10m");
|
||||
|
||||
if ( ! TCAP(fc::t_key_mouse) )
|
||||
TCAP(fc::t_key_mouse) = \
|
||||
C_STR(CSI "M");
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermcapQuirks::init_termcap_teraterm_quirks()
|
||||
{
|
||||
// Tera Term eat_nl_glitch fix
|
||||
FTermcap::eat_nl_glitch = true;
|
||||
|
||||
// Tera Term color settings
|
||||
TCAP(fc::t_set_a_foreground) = \
|
||||
C_STR(CSI "38;5;%p1%dm");
|
||||
TCAP(fc::t_set_a_background) = \
|
||||
C_STR(CSI "48;5;%p1%dm");
|
||||
TCAP(fc::t_exit_attribute_mode) = \
|
||||
C_STR(CSI "0m" SI);
|
||||
TCAP(fc::t_orig_pair) = \
|
||||
C_STR(CSI "39;49m");
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermcapQuirks::init_termcap_sun_quirks()
|
||||
{
|
||||
// Sun Microsystems workstation console eat_nl_glitch fix
|
||||
FTermcap::eat_nl_glitch = true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermcapQuirks::init_termcap_screen_quirks()
|
||||
{
|
||||
// Fallback if "Ic" is not found
|
||||
if ( ! TCAP(fc::t_initialize_color) )
|
||||
{
|
||||
if ( term_detection->isTmuxTerm() )
|
||||
{
|
||||
TCAP(fc::t_initialize_color) = \
|
||||
C_STR(ESC "Ptmux;" ESC OSC "4;%p1%d;rgb:"
|
||||
"%p2%{255}%*%{1000}%/%2.2X/"
|
||||
"%p3%{255}%*%{1000}%/%2.2X/"
|
||||
"%p4%{255}%*%{1000}%/%2.2X" BEL ESC "\\");
|
||||
}
|
||||
else
|
||||
{
|
||||
TCAP(fc::t_initialize_color) = \
|
||||
C_STR(ESC "P" OSC "4;%p1%d;rgb:"
|
||||
"%p2%{255}%*%{1000}%/%2.2X/"
|
||||
"%p3%{255}%*%{1000}%/%2.2X/"
|
||||
"%p4%{255}%*%{1000}%/%2.2X" BEL ESC "\\");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermcapQuirks::init_termcap_general_quirks()
|
||||
{
|
||||
static const int not_available = -1;
|
||||
|
||||
if ( FTermcap::tabstop == not_available )
|
||||
FTermcap::tabstop = 8;
|
||||
|
||||
if ( FTermcap::attr_without_color == not_available )
|
||||
FTermcap::attr_without_color = 0;
|
||||
|
||||
// Fallback if "AF" is not found
|
||||
if ( ! TCAP(fc::t_set_a_foreground) )
|
||||
TCAP(fc::t_set_a_foreground) = \
|
||||
C_STR(CSI "3%p1%dm");
|
||||
|
||||
// Fallback if "AB" is not found
|
||||
if ( ! TCAP(fc::t_set_a_background) )
|
||||
TCAP(fc::t_set_a_background) = \
|
||||
C_STR(CSI "4%p1%dm");
|
||||
|
||||
// Fallback if "Ic" is not found
|
||||
if ( ! TCAP(fc::t_initialize_color) )
|
||||
{
|
||||
TCAP(fc::t_initialize_color) = \
|
||||
C_STR(OSC "P%p1%x"
|
||||
"%p2%{255}%*%{1000}%/%02x"
|
||||
"%p3%{255}%*%{1000}%/%02x"
|
||||
"%p4%{255}%*%{1000}%/%02x");
|
||||
}
|
||||
|
||||
// Fallback if "ti" is not found
|
||||
if ( ! TCAP(fc::t_enter_ca_mode) )
|
||||
TCAP(fc::t_enter_ca_mode) = \
|
||||
C_STR(ESC "7" CSI "?47h");
|
||||
|
||||
// Fallback if "te" is not found
|
||||
if ( ! TCAP(fc::t_exit_ca_mode) )
|
||||
TCAP(fc::t_exit_ca_mode) = \
|
||||
C_STR(CSI "?47l" ESC "8" CSI "m");
|
||||
|
||||
// Set ansi move if "cm" is not found
|
||||
if ( ! TCAP(fc::t_cursor_address) )
|
||||
TCAP(fc::t_cursor_address) = \
|
||||
C_STR(CSI "%i%p1%d;%p2%dH");
|
||||
|
||||
// Test for standard ECMA-48 (ANSI X3.64) terminal
|
||||
if ( TCAP(fc::t_exit_underline_mode)
|
||||
&& std::strncmp(TCAP(fc::t_exit_underline_mode), CSI "24m", 5) == 0 )
|
||||
{
|
||||
// Seems to be a ECMA-48 (ANSI X3.64) compatible terminal
|
||||
TCAP(fc::t_enter_dbl_underline_mode) = \
|
||||
C_STR(CSI "21m"); // Exit single underline, too
|
||||
|
||||
TCAP(fc::t_exit_dbl_underline_mode) = \
|
||||
C_STR(CSI "24m");
|
||||
|
||||
TCAP(fc::t_exit_bold_mode) = \
|
||||
C_STR(CSI "22m"); // Exit dim, too
|
||||
|
||||
TCAP(fc::t_exit_dim_mode) = \
|
||||
C_STR(CSI "22m");
|
||||
|
||||
TCAP(fc::t_exit_underline_mode) = \
|
||||
C_STR(CSI "24m");
|
||||
|
||||
TCAP(fc::t_exit_blink_mode) = \
|
||||
C_STR(CSI "25m");
|
||||
|
||||
TCAP(fc::t_exit_reverse_mode) = \
|
||||
C_STR(CSI "27m");
|
||||
|
||||
TCAP(fc::t_exit_secure_mode) = \
|
||||
C_STR(CSI "28m");
|
||||
|
||||
TCAP(fc::t_enter_crossed_out_mode) = \
|
||||
C_STR(CSI "9m");
|
||||
|
||||
TCAP(fc::t_exit_crossed_out_mode) = \
|
||||
C_STR(CSI "29m");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,893 @@
|
|||
/***********************************************************************
|
||||
* ftermdetection.cpp - Detection of the terminal type *
|
||||
* *
|
||||
* This file is part of the Final Cut widget toolkit *
|
||||
* *
|
||||
* Copyright 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 *
|
||||
* as published by the Free Software Foundation; either version 3 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* The Final Cut is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this program. If not, see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************/
|
||||
|
||||
#include "final/fterm.h"
|
||||
#include "final/ftermdetection.h"
|
||||
|
||||
// static class attributes
|
||||
FTermDetection::terminalType FTermDetection::terminal_type = \
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
FTermDetection::colorEnv FTermDetection::color_env;
|
||||
FTermDetection::secondaryDA FTermDetection::secondary_da;
|
||||
char FTermDetection::termtype[256] = {};
|
||||
char FTermDetection::termfilename[256] = {};
|
||||
bool FTermDetection::decscusr_support;
|
||||
bool FTermDetection::terminal_detection;
|
||||
bool FTermDetection::color256;
|
||||
const FString* FTermDetection::answer_back = 0;
|
||||
const FString* FTermDetection::sec_da = 0;
|
||||
int FTermDetection::gnome_terminal_id;
|
||||
|
||||
#if DEBUG
|
||||
char FTermDetection::termtype_256color[256] = {};
|
||||
char FTermDetection::termtype_Answerback[256] = {};
|
||||
char FTermDetection::termtype_SecDA[256] = {};
|
||||
#endif
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// class FTermDetection
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// constructors and destructor
|
||||
//----------------------------------------------------------------------
|
||||
FTermDetection::FTermDetection()
|
||||
{
|
||||
// Preset to true
|
||||
terminal_detection = true;
|
||||
|
||||
// Preset to false
|
||||
decscusr_support = false;
|
||||
|
||||
// Gnome terminal id from SecDA
|
||||
// Example: vte version 0.40.0 = 0 * 100 + 40 * 100 + 0 = 4000
|
||||
// a.b.c = a * 100 + b * 100 + c
|
||||
gnome_terminal_id = 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
FTermDetection::~FTermDetection() // destructor
|
||||
{
|
||||
if ( sec_da )
|
||||
delete sec_da;
|
||||
|
||||
if ( answer_back )
|
||||
delete answer_back;
|
||||
}
|
||||
|
||||
|
||||
// public methods of FTermDetection
|
||||
//----------------------------------------------------------------------
|
||||
void FTermDetection::setTermFileName (char term_filename[])
|
||||
{
|
||||
if ( ! term_filename )
|
||||
return;
|
||||
|
||||
std::strncpy ( termfilename
|
||||
, term_filename
|
||||
, std::strlen(term_filename) + 1 );
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermDetection::detect()
|
||||
{
|
||||
// Set the variable 'termtype' to the predefined type of the terminal
|
||||
getSystemTermType();
|
||||
|
||||
// Analysis the termtype
|
||||
termtypeAnalysis();
|
||||
|
||||
// Terminal detection
|
||||
detectTerminal();
|
||||
}
|
||||
|
||||
|
||||
// private methods of FTermDetection
|
||||
//----------------------------------------------------------------------
|
||||
void FTermDetection::getSystemTermType()
|
||||
{
|
||||
// Import the untrusted environment variable TERM
|
||||
const char* const& term_env = std::getenv(C_STR("TERM"));
|
||||
|
||||
if ( term_env )
|
||||
{
|
||||
// Save name in termtype
|
||||
std::strncpy (termtype, term_env, sizeof(termtype) - 1);
|
||||
return;
|
||||
}
|
||||
else if ( *termfilename ) // 1st fallback: use the teminal file name
|
||||
{
|
||||
getTTYtype(); // Look into /etc/ttytype
|
||||
|
||||
#if F_HAVE_GETTTYNAM
|
||||
if ( getTTYSFileEntry() ) // Look into /etc/ttys
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
// 2nd fallback: use vt100 if not found
|
||||
std::strncpy (termtype, C_STR("vt100"), 6);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermDetection::getTTYtype()
|
||||
{
|
||||
// Analyse /etc/ttytype and get the term name
|
||||
// ------------------------------------------
|
||||
// file format:
|
||||
// <terminal type> <whitespace> <tty name>
|
||||
//
|
||||
// Example:
|
||||
// linux tty1
|
||||
// vt100 ttys0
|
||||
|
||||
// Get term basename
|
||||
const char* term_basename = std::strrchr(termfilename, '/');
|
||||
|
||||
if ( term_basename == 0 )
|
||||
term_basename = termfilename;
|
||||
else
|
||||
term_basename++;
|
||||
|
||||
std::FILE *fp;
|
||||
|
||||
if ( (fp = std::fopen("/etc/ttytype", "r")) != 0 )
|
||||
{
|
||||
char* p;
|
||||
char str[BUFSIZ];
|
||||
|
||||
// Read and parse the file
|
||||
while ( fgets(str, sizeof(str) - 1, fp) != 0 )
|
||||
{
|
||||
char* name;
|
||||
char* type;
|
||||
type = name = 0; // 0 == not found
|
||||
p = str;
|
||||
|
||||
while ( *p )
|
||||
{
|
||||
if ( std::isspace(uChar(*p)) )
|
||||
*p = '\0';
|
||||
else if ( type == 0 )
|
||||
type = p;
|
||||
else if ( name == 0 && p != str && p[-1] == '\0' )
|
||||
name = p;
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
if ( type != 0 && name != 0 && ! std::strcmp(name, term_basename) )
|
||||
{
|
||||
// Save name in termtype
|
||||
std::strncpy (termtype, type, sizeof(termtype) - 1);
|
||||
std::fclose(fp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
#if F_HAVE_GETTTYNAM
|
||||
//----------------------------------------------------------------------
|
||||
bool FTermDetection::getTTYSFileEntry()
|
||||
{
|
||||
// Analyse /etc/ttys and get the term name
|
||||
|
||||
// get term basename
|
||||
const char* term_basename = std::strrchr(termfilename, '/');
|
||||
|
||||
if ( term_basename == 0 )
|
||||
term_basename = termfilename;
|
||||
else
|
||||
term_basename++;
|
||||
|
||||
struct ttyent* ttys_entryt;
|
||||
ttys_entryt = getttynam(term_basename);
|
||||
|
||||
if ( ttys_entryt )
|
||||
{
|
||||
char* type = ttys_entryt->ty_type;
|
||||
|
||||
if ( type != 0 )
|
||||
{
|
||||
// Save name in termtype
|
||||
std::strncpy (termtype, type, sizeof(termtype) - 1);
|
||||
endttyent();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
endttyent();
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermDetection::termtypeAnalysis()
|
||||
{
|
||||
// Cygwin console
|
||||
if ( std::strncmp(termtype, "cygwin", 6) == 0 )
|
||||
terminal_type.cygwin = true;
|
||||
|
||||
// rxvt terminal emulator (native MS Window System port) on cygwin
|
||||
if ( std::strncmp(termtype, "rxvt-cygwin-native", 18) == 0 )
|
||||
terminal_type.rxvt = true;
|
||||
|
||||
// Ansi terminal
|
||||
if ( std::strncmp(termtype, "ansi", 4) == 0 )
|
||||
{
|
||||
terminal_detection = false;
|
||||
terminal_type.ansi = true;
|
||||
}
|
||||
|
||||
// Sun Microsystems workstation console
|
||||
if ( std::strncmp(termtype, "sun", 3) == 0 )
|
||||
{
|
||||
terminal_detection = false;
|
||||
terminal_type.sun_con = true;
|
||||
}
|
||||
|
||||
// Kterm
|
||||
if ( std::strncmp(termtype, "kterm", 5) == 0 )
|
||||
{
|
||||
terminal_detection = false;
|
||||
terminal_type.kterm = true;
|
||||
}
|
||||
|
||||
// Linux console
|
||||
if ( std::strncmp(termtype, C_STR("linux"), 5) == 0
|
||||
|| std::strncmp(termtype, C_STR("con"), 3) == 0 )
|
||||
terminal_type.linux_con = true;
|
||||
|
||||
// NetBSD workstation console
|
||||
if ( std::strncmp(termtype, C_STR("wsvt25"), 6) == 0 )
|
||||
terminal_type.netbsd_con = true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermDetection::detectTerminal()
|
||||
{
|
||||
// Terminal detection
|
||||
|
||||
char* new_termtype = 0;
|
||||
|
||||
if ( terminal_detection )
|
||||
{
|
||||
FTermios::setCaptureSendCharacters();
|
||||
|
||||
// Initialize 256 colors terminals
|
||||
new_termtype = init_256colorTerminal();
|
||||
|
||||
// Identify the terminal via the answerback-message
|
||||
new_termtype = parseAnswerbackMsg (new_termtype);
|
||||
|
||||
// Identify the terminal via the secondary device attributes (SEC_DA)
|
||||
new_termtype = parseSecDA (new_termtype);
|
||||
|
||||
// Determines the maximum number of colors
|
||||
new_termtype = determineMaxColor(new_termtype);
|
||||
|
||||
FTermios::unsetCaptureSendCharacters();
|
||||
}
|
||||
|
||||
//
|
||||
// Additional termtype analysis
|
||||
//
|
||||
|
||||
// Test if the terminal is a xterm
|
||||
if ( std::strncmp(termtype, C_STR("xterm"), 5) == 0
|
||||
|| std::strncmp(termtype, C_STR("Eterm"), 5) == 0 )
|
||||
{
|
||||
terminal_type.xterm = true;
|
||||
|
||||
// Each xterm should be able to use at least 16 colors
|
||||
if ( ! new_termtype && std::strlen(termtype) == 5 )
|
||||
new_termtype = C_STR("xterm-16color");
|
||||
}
|
||||
|
||||
// set the new environment variable TERM
|
||||
if ( new_termtype )
|
||||
{
|
||||
setenv(C_STR("TERM"), new_termtype, 1);
|
||||
std::strncpy (termtype, new_termtype, std::strlen(new_termtype) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
char* FTermDetection::init_256colorTerminal()
|
||||
{
|
||||
char* new_termtype = 0;
|
||||
|
||||
if ( get256colorEnvString() )
|
||||
color256 = true;
|
||||
else if ( std::strstr (termtype, "256color") )
|
||||
color256 = true;
|
||||
else
|
||||
color256 = false;
|
||||
|
||||
new_termtype = termtype_256color_quirks();
|
||||
|
||||
#if DEBUG
|
||||
if ( new_termtype )
|
||||
std::strncpy ( termtype_256color
|
||||
, new_termtype
|
||||
, std::strlen(new_termtype) + 1 );
|
||||
#endif
|
||||
|
||||
return new_termtype;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool FTermDetection::get256colorEnvString()
|
||||
{
|
||||
// Enable 256 color capabilities
|
||||
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 ( color_env.string1 != 0 )
|
||||
return true;
|
||||
|
||||
if ( color_env.string2 != 0 )
|
||||
return true;
|
||||
|
||||
if ( color_env.string3 != 0 )
|
||||
return true;
|
||||
|
||||
if ( color_env.string4 != 0 )
|
||||
return true;
|
||||
|
||||
if ( color_env.string5 != 0 )
|
||||
return true;
|
||||
|
||||
if ( color_env.string6 != 0 )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
char* FTermDetection::termtype_256color_quirks()
|
||||
{
|
||||
char* new_termtype = 0;
|
||||
|
||||
if ( ! color256 )
|
||||
return new_termtype;
|
||||
|
||||
if ( std::strncmp(termtype, "xterm", 5) == 0 )
|
||||
new_termtype = C_STR("xterm-256color");
|
||||
|
||||
if ( std::strncmp(termtype, "screen", 6) == 0 )
|
||||
{
|
||||
new_termtype = C_STR("screen-256color");
|
||||
terminal_type.screen = true;
|
||||
char* tmux = std::getenv("TMUX");
|
||||
|
||||
if ( tmux && std::strlen(tmux) != 0 )
|
||||
terminal_type.tmux = true;
|
||||
}
|
||||
|
||||
if ( std::strncmp(termtype, "Eterm", 5) == 0 )
|
||||
new_termtype = C_STR("Eterm-256color");
|
||||
|
||||
if ( std::strncmp(termtype, "mlterm", 6) == 0 )
|
||||
{
|
||||
new_termtype = C_STR("mlterm-256color");
|
||||
terminal_type.mlterm = true;
|
||||
}
|
||||
|
||||
if ( std::strncmp(termtype, "rxvt", 4) != 0
|
||||
&& color_env.string1
|
||||
&& std::strncmp(color_env.string1, "rxvt-xpm", 8) == 0 )
|
||||
{
|
||||
new_termtype = C_STR("rxvt-256color");
|
||||
terminal_type.rxvt = true;
|
||||
}
|
||||
|
||||
if ( (color_env.string5 && std::strlen(color_env.string5) > 0)
|
||||
|| (color_env.string6 && std::strlen(color_env.string6) > 0) )
|
||||
terminal_type.kde_konsole = true;
|
||||
|
||||
if ( (color_env.string1 && std::strncmp(color_env.string1, "gnome-terminal", 14) == 0)
|
||||
|| color_env.string2 )
|
||||
{
|
||||
terminal_type.gnome_terminal = true;
|
||||
// Each gnome-terminal should be able to use 256 colors
|
||||
color256 = true;
|
||||
|
||||
if ( ! isScreenTerm() )
|
||||
new_termtype = C_STR("gnome-256color");
|
||||
}
|
||||
|
||||
return new_termtype;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
char* FTermDetection::determineMaxColor (char current_termtype[])
|
||||
{
|
||||
// Determine xterm maximum number of colors via OSC 4
|
||||
|
||||
char* new_termtype = current_termtype;
|
||||
|
||||
if ( ! color256
|
||||
&& ! isCygwinTerminal()
|
||||
&& ! isTeraTerm()
|
||||
&& ! isLinuxTerm()
|
||||
&& ! isNetBSDTerm()
|
||||
&& ! getXTermColorName(0).isEmpty() )
|
||||
{
|
||||
if ( ! getXTermColorName(256).isEmpty() )
|
||||
{
|
||||
if ( isPuttyTerminal() )
|
||||
new_termtype = C_STR("putty-256color");
|
||||
else
|
||||
new_termtype = C_STR("xterm-256color");
|
||||
}
|
||||
else if ( ! getXTermColorName(87).isEmpty() )
|
||||
{
|
||||
new_termtype = C_STR("xterm-88color");
|
||||
}
|
||||
else if ( ! getXTermColorName(15).isEmpty() )
|
||||
{
|
||||
new_termtype = C_STR("xterm-16color");
|
||||
}
|
||||
}
|
||||
|
||||
return new_termtype;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
const FString FTermDetection::getXTermColorName (int color)
|
||||
{
|
||||
FString color_str("");
|
||||
|
||||
fd_set ifds;
|
||||
struct timeval tv;
|
||||
int stdin_no = FTermios::getStdIn();
|
||||
|
||||
char temp[512] = {};
|
||||
FTerm::putstringf (OSC "4;%d;?" BEL, color); // get color
|
||||
std::fflush(stdout);
|
||||
|
||||
FD_ZERO(&ifds);
|
||||
FD_SET(stdin_no, &ifds);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 150000; // 150 ms
|
||||
|
||||
// read the terminal answer
|
||||
if ( select (stdin_no + 1, &ifds, 0, 0, &tv) > 0 )
|
||||
{
|
||||
if ( std::scanf("\033]4;%10d;%509[^\n]s", &color, temp) == 2 )
|
||||
{
|
||||
std::size_t n = std::strlen(temp);
|
||||
|
||||
// BEL + '\0' = string terminator
|
||||
if ( n >= 6 && temp[n - 1] == BEL[0] && temp[n] == '\0' )
|
||||
temp[n - 1] = '\0';
|
||||
|
||||
// Esc + \ = OSC string terminator (mintty)
|
||||
if ( n >= 6 && temp[n - 2] == ESC[0] && temp[n - 1] == '\\' )
|
||||
temp[n - 2] = '\0';
|
||||
|
||||
color_str = temp;
|
||||
}
|
||||
}
|
||||
|
||||
return color_str;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
char* FTermDetection::parseAnswerbackMsg (char current_termtype[])
|
||||
{
|
||||
char* new_termtype = current_termtype;
|
||||
|
||||
// send ENQ and read the answerback message
|
||||
try
|
||||
{
|
||||
answer_back = new FString(getAnswerbackMsg());
|
||||
}
|
||||
catch (const std::bad_alloc& ex)
|
||||
{
|
||||
std::cerr << "not enough memory to alloc " << ex.what() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( *answer_back == "PuTTY" )
|
||||
{
|
||||
terminal_type.putty = true;
|
||||
|
||||
if ( color256 )
|
||||
new_termtype = C_STR("putty-256color");
|
||||
else
|
||||
new_termtype = C_STR("putty");
|
||||
}
|
||||
|
||||
// cygwin needs a backspace to delete the '♣' char
|
||||
if ( isCygwinTerminal() )
|
||||
FTerm::putstring (BS " " BS);
|
||||
|
||||
#if DEBUG
|
||||
if ( new_termtype )
|
||||
std::strncpy ( termtype_Answerback
|
||||
, new_termtype
|
||||
, std::strlen(new_termtype) + 1 );
|
||||
#endif
|
||||
|
||||
return new_termtype;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
const FString FTermDetection::getAnswerbackMsg()
|
||||
{
|
||||
FString answerback = "";
|
||||
|
||||
fd_set ifds;
|
||||
struct timeval tv;
|
||||
char temp[10] = {};
|
||||
int stdin_no = FTermios::getStdIn();
|
||||
|
||||
std::putchar (ENQ[0]); // Send enquiry character
|
||||
std::fflush(stdout);
|
||||
|
||||
FD_ZERO(&ifds);
|
||||
FD_SET(stdin_no, &ifds);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 150000; // 150 ms
|
||||
|
||||
// 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;
|
||||
|
||||
return answerback;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
char* FTermDetection::parseSecDA (char current_termtype[])
|
||||
{
|
||||
// The Linux console and older cygwin terminals knows no Sec_DA
|
||||
if ( isLinuxTerm() || isCygwinTerminal() )
|
||||
return current_termtype;
|
||||
|
||||
try
|
||||
{
|
||||
// Secondary device attributes (SEC_DA) <- decTerminalID string
|
||||
sec_da = new FString(getSecDA());
|
||||
}
|
||||
catch (const std::bad_alloc& ex)
|
||||
{
|
||||
std::cerr << "not enough memory to alloc " << ex.what() << std::endl;
|
||||
return current_termtype;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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 )
|
||||
std::strncpy ( termtype_SecDA
|
||||
, new_termtype
|
||||
, std::strlen(new_termtype) + 1 );
|
||||
#endif
|
||||
|
||||
return new_termtype;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
const FString FTermDetection::getSecDA()
|
||||
{
|
||||
FString sec_da_str = "";
|
||||
|
||||
int a = 0
|
||||
, b = 0
|
||||
, c = 0
|
||||
, stdin_no = FTermios::getStdIn();
|
||||
fd_set ifds;
|
||||
struct timeval tv;
|
||||
|
||||
// Get the secondary device attributes
|
||||
#if defined(__CYGWIN__)
|
||||
puts (SECDA);
|
||||
#else
|
||||
FTerm::putstring (SECDA);
|
||||
#endif
|
||||
std::fflush(stdout);
|
||||
|
||||
FD_ZERO(&ifds);
|
||||
FD_SET(stdin_no, &ifds);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 600000; // 600 ms
|
||||
|
||||
// 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);
|
||||
|
||||
return sec_da_str;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
char* FTermDetection::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 32: // Tera Term
|
||||
new_termtype = secDA_Analysis_32(current_termtype);
|
||||
break;
|
||||
|
||||
case 41: // DEC VT420
|
||||
case 61: // DEC VT510
|
||||
case 64: // DEC VT520
|
||||
case 65: // DEC VT525
|
||||
case 67: // Cygwin
|
||||
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 ( isGnomeTerminal() && secondary_da.terminal_id_type != 1 )
|
||||
terminal_type.gnome_terminal = false;
|
||||
|
||||
if ( isKdeTerminal() && secondary_da.terminal_id_type != 0 )
|
||||
terminal_type.kde_konsole = false;
|
||||
|
||||
return new_termtype;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline char* FTermDetection::secDA_Analysis_0 (char current_termtype[])
|
||||
{
|
||||
// Terminal ID 0 - DEC VT100
|
||||
|
||||
char* new_termtype = current_termtype;
|
||||
|
||||
if ( secondary_da.terminal_id_version == 115 )
|
||||
terminal_type.kde_konsole = true;
|
||||
else if ( secondary_da.terminal_id_version == 136 )
|
||||
terminal_type.putty = true; // PuTTY
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
if ( FTerm::isFreeBSDConsole() )
|
||||
terminal_type.freebsd_con = true;
|
||||
#endif
|
||||
|
||||
return new_termtype;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline char* FTermDetection::secDA_Analysis_1 (char current_termtype[])
|
||||
{
|
||||
// Terminal ID 1 - DEC VT220
|
||||
|
||||
char* new_termtype = current_termtype;
|
||||
|
||||
if ( secondary_da.terminal_id_version > 1000 )
|
||||
{
|
||||
terminal_type.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* FTermDetection::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 && FTerm::isWSConsConsole() )
|
||||
{
|
||||
// NetBSD/OpenBSD workstation console
|
||||
if ( std::strncmp(termtype, C_STR("wsvt25"), 6) == 0 )
|
||||
terminal_type.netbsd_con = true;
|
||||
else if ( std::strncmp(termtype, C_STR("vt220"), 5) == 0 )
|
||||
{
|
||||
terminal_type.openbsd_con = true;
|
||||
new_termtype = C_STR("pccon");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return new_termtype;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline char* FTermDetection::secDA_Analysis_32 (char[])
|
||||
{
|
||||
// Terminal ID 32 - Tera Term
|
||||
|
||||
char* new_termtype;
|
||||
terminal_type.tera_term = true;
|
||||
new_termtype = C_STR("teraterm");
|
||||
return new_termtype;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline char* FTermDetection::secDA_Analysis_77 (char[])
|
||||
{
|
||||
// Terminal ID 77 - mintty
|
||||
|
||||
char* new_termtype;
|
||||
terminal_type.mintty = true;
|
||||
new_termtype = C_STR("xterm-256color");
|
||||
std::fflush(stdout);
|
||||
return new_termtype;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline char* FTermDetection::secDA_Analysis_82 (char current_termtype[])
|
||||
{
|
||||
// Terminal ID 82 - rxvt
|
||||
|
||||
char* new_termtype = current_termtype;
|
||||
terminal_type.rxvt = true;
|
||||
|
||||
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* FTermDetection::secDA_Analysis_83 (char current_termtype[])
|
||||
{
|
||||
// Terminal ID 83 - screen
|
||||
|
||||
char* new_termtype = current_termtype;
|
||||
terminal_type.screen = true;
|
||||
return new_termtype;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline char* FTermDetection::secDA_Analysis_85 (char current_termtype[])
|
||||
{
|
||||
// Terminal ID 85 - rxvt-unicode
|
||||
|
||||
char* new_termtype = current_termtype;
|
||||
terminal_type.rxvt = true;
|
||||
terminal_type.urxvt = 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;
|
||||
}
|
|
@ -0,0 +1,223 @@
|
|||
/***********************************************************************
|
||||
* ftermios.cpp - Provides access to POSIX tty I/O control *
|
||||
* *
|
||||
* This file is part of the Final Cut widget toolkit *
|
||||
* *
|
||||
* Copyright 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 *
|
||||
* as published by the Free Software Foundation; either version 3 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* The Final Cut is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this program. If not, see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************/
|
||||
|
||||
#include "final/ftermios.h"
|
||||
|
||||
// static class attributes
|
||||
int FTermios::stdin_no;
|
||||
int FTermios::stdout_no;
|
||||
bool FTermios::raw_mode;
|
||||
termios FTermios::term_init;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// class FTermios
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// constructors and destructor
|
||||
//----------------------------------------------------------------------
|
||||
FTermios::FTermios()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
FTermios::~FTermios() // destructor
|
||||
{ }
|
||||
|
||||
|
||||
// public methods of FTermios
|
||||
//----------------------------------------------------------------------
|
||||
void FTermios::init()
|
||||
{
|
||||
// Assertion: programm start in cooked mode
|
||||
raw_mode = false;
|
||||
|
||||
// Get file descriptor for standard input and standard output
|
||||
stdin_no = fileno(stdin);
|
||||
stdout_no = fileno(stdout);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
termios FTermios::getTTY()
|
||||
{
|
||||
struct termios t;
|
||||
tcgetattr (stdin_no, &t);
|
||||
return t;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermios::setTTY (const termios& t)
|
||||
{
|
||||
tcsetattr (stdin_no, TCSADRAIN, &t);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermios::storeTTYsettings()
|
||||
{
|
||||
// Store termios settings
|
||||
term_init = getTTY();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermios::restoreTTYsettings()
|
||||
{
|
||||
// Restore termios settings
|
||||
setTTY (term_init);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermios::setHardwareEcho()
|
||||
{
|
||||
// Info under: man 3 termios
|
||||
struct termios t;
|
||||
tcgetattr (stdin_no, &t);
|
||||
|
||||
// local mode
|
||||
t.c_lflag &= uInt(ECHO | ECHONL);
|
||||
|
||||
// input mode
|
||||
t.c_iflag &= uInt(ICRNL | INLCR | IGNCR);
|
||||
|
||||
// output mode
|
||||
t.c_oflag &= uInt(ONLCR);
|
||||
|
||||
// set the new termios settings
|
||||
setTTY (t);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermios::unsetHardwareEcho()
|
||||
{
|
||||
// Info under: man 3 termios
|
||||
struct termios t;
|
||||
tcgetattr (stdin_no, &t);
|
||||
|
||||
// local mode
|
||||
t.c_lflag &= uInt(~(ECHO | ECHONL));
|
||||
|
||||
// input mode
|
||||
t.c_iflag &= uInt(~(ICRNL | INLCR | IGNCR));
|
||||
|
||||
// output mode
|
||||
t.c_oflag &= uInt(~ONLCR);
|
||||
|
||||
// set the new termios settings
|
||||
setTTY (t);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermios::setCaptureSendCharacters()
|
||||
{
|
||||
struct termios t;
|
||||
tcgetattr (stdin_no, &t);
|
||||
t.c_lflag &= uInt(~(ICANON | ECHO));
|
||||
t.c_cc[VTIME] = 1; // Timeout in deciseconds
|
||||
t.c_cc[VMIN] = 0; // Minimum number of characters
|
||||
tcsetattr (stdin_no, TCSANOW, &t);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTermios::unsetCaptureSendCharacters()
|
||||
{
|
||||
struct termios t;
|
||||
tcgetattr (stdin_no, &t);
|
||||
t.c_lflag |= uInt(ICANON | ECHO);
|
||||
t.c_cc[VTIME] = 0; // Timeout in deciseconds
|
||||
t.c_cc[VMIN] = 1; // Minimum number of characters
|
||||
setTTY (t);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool FTermios::setRawMode (bool on)
|
||||
{
|
||||
// set + unset flags for raw mode
|
||||
if ( on == raw_mode )
|
||||
return raw_mode;
|
||||
|
||||
// Info under: man 3 termios
|
||||
struct termios t;
|
||||
tcgetattr (stdin_no, &t);
|
||||
|
||||
if ( on )
|
||||
{
|
||||
// local mode
|
||||
#if DEBUG
|
||||
// Exit with ctrl-c only if compiled with "DEBUG" option
|
||||
t.c_lflag &= uInt(~(ICANON | IEXTEN));
|
||||
#else
|
||||
t.c_lflag &= uInt(~(ICANON | ISIG | IEXTEN));
|
||||
#endif
|
||||
|
||||
// input mode
|
||||
t.c_iflag &= uInt(~(IXON | BRKINT | PARMRK));
|
||||
|
||||
// defines the terminal special characters for noncanonical read
|
||||
t.c_cc[VTIME] = 0; // Timeout in deciseconds
|
||||
t.c_cc[VMIN] = 1; // Minimum number of characters
|
||||
|
||||
// set the new termios settings
|
||||
setTTY (t);
|
||||
raw_mode = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// local mode
|
||||
t.c_lflag |= uInt(ISIG | ICANON | (term_init.c_lflag & IEXTEN));
|
||||
|
||||
// input mode
|
||||
t.c_iflag |= uInt(IXON | BRKINT | PARMRK);
|
||||
|
||||
// set the new termios settings
|
||||
setTTY (t);
|
||||
raw_mode = false;
|
||||
}
|
||||
|
||||
return raw_mode;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
uInt FTermios::getBaudRate()
|
||||
{
|
||||
std::map<speed_t,uInt> outspeed;
|
||||
outspeed[B0] = 0; // hang up
|
||||
outspeed[B50] = 50; // 50 baud
|
||||
outspeed[B75] = 75; // 75 baud
|
||||
outspeed[B110] = 110; // 110 baud
|
||||
outspeed[B134] = 134; // 134.5 baud
|
||||
outspeed[B150] = 150; // 150 baud
|
||||
outspeed[B200] = 200; // 200 baud
|
||||
outspeed[B300] = 300; // 300 baud
|
||||
outspeed[B600] = 600; // 600 baud
|
||||
outspeed[B1200] = 1200; // 1,200 baud
|
||||
outspeed[B1800] = 1800; // 1,800 baud
|
||||
outspeed[B2400] = 2400; // 2,400 baud
|
||||
outspeed[B4800] = 4800; // 4,800 baud
|
||||
outspeed[B9600] = 9600; // 9,600 baud
|
||||
outspeed[B19200] = 19200; // 19,200 baud
|
||||
outspeed[B38400] = 38400; // 38,400 baud
|
||||
outspeed[B57600] = 57600; // 57,600 baud
|
||||
outspeed[B115200] = 115200; // 115,200 baud
|
||||
outspeed[B230400] = 230400; // 230,400 baud
|
||||
|
||||
return outspeed[cfgetospeed(&term_init)];
|
||||
}
|
Loading…
Reference in New Issue