2018-05-02 12:31:21 +02:00
|
|
|
/***********************************************************************
|
|
|
|
* 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"
|
2018-07-15 19:52:59 +02:00
|
|
|
#include "final/fconfig.h"
|
2018-10-01 22:27:54 +02:00
|
|
|
#include "final/ftermdata.h"
|
2018-05-02 12:31:21 +02:00
|
|
|
#include "final/ftermios.h"
|
|
|
|
#include "final/ftypes.h"
|
|
|
|
|
2018-09-20 23:59:01 +02:00
|
|
|
namespace finalcut
|
|
|
|
{
|
2018-05-02 12:31:21 +02:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// class FTermDetection
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
#pragma pack(push)
|
|
|
|
#pragma pack(1)
|
|
|
|
|
|
|
|
class FTermDetection
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// Typedefs
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
// byte #0
|
|
|
|
uInt8 ansi : 1;
|
2018-09-14 22:42:56 +02:00
|
|
|
uInt8 xterm : 1;
|
2018-05-02 12:31:21 +02:00
|
|
|
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
|
2018-09-24 04:02:35 +02:00
|
|
|
virtual ~FTermDetection();
|
2018-05-02 12:31:21 +02:00
|
|
|
|
|
|
|
// Accessor
|
2018-08-09 00:04:00 +02:00
|
|
|
const char* getClassName() const;
|
2018-05-02 12:31:21 +02:00
|
|
|
static char* getTermType();
|
|
|
|
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 isAnsiTerminal();
|
2018-09-14 22:42:56 +02:00
|
|
|
static bool isXTerminal();
|
2018-05-02 12:31:21 +02:00
|
|
|
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 isCygwinTerminal();
|
|
|
|
static bool isMinttyTerm();
|
|
|
|
static bool isLinuxTerm();
|
|
|
|
static bool isFreeBSDTerm();
|
|
|
|
static bool isNetBSDTerm();
|
|
|
|
static bool isOpenBSDTerm();
|
2018-09-14 22:42:56 +02:00
|
|
|
static bool isSunTerminal();
|
2018-05-02 12:31:21 +02:00
|
|
|
static bool isScreenTerm();
|
|
|
|
static bool isTmuxTerm();
|
2018-05-27 19:43:18 +02:00
|
|
|
static bool canDisplay256Colors();
|
2018-05-02 12:31:21 +02:00
|
|
|
static bool hasTerminalDetection();
|
|
|
|
static bool hasSetCursorStyleSupport();
|
|
|
|
|
|
|
|
// Mutators
|
|
|
|
static void setAnsiTerminal (bool);
|
2018-09-14 22:42:56 +02:00
|
|
|
static void setXTerminal (bool);
|
2018-05-02 12:31:21 +02:00
|
|
|
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 setCygwinTerminal (bool);
|
|
|
|
static void setMinttyTerm (bool);
|
|
|
|
static void setLinuxTerm (bool);
|
|
|
|
static void setFreeBSDTerm (bool);
|
|
|
|
static void setNetBSDTerm (bool);
|
|
|
|
static void setOpenBSDTerm (bool);
|
2018-09-14 22:42:56 +02:00
|
|
|
static void setSunTerminal (bool);
|
2018-05-02 12:31:21 +02:00
|
|
|
static void setScreenTerm (bool);
|
|
|
|
static void setTmuxTerm (bool);
|
|
|
|
static void setTerminalDetection (bool);
|
2018-11-01 21:29:54 +01:00
|
|
|
static void setFTermData (FTermData*);
|
2018-09-16 19:33:40 +02:00
|
|
|
static void setTtyTypeFileName (char[]);
|
2018-05-02 12:31:21 +02:00
|
|
|
|
|
|
|
// 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
|
2018-12-22 15:33:23 +01:00
|
|
|
static void deallocation();
|
2018-05-02 12:31:21 +02:00
|
|
|
static void getSystemTermType();
|
2018-09-16 19:33:40 +02:00
|
|
|
static bool getTTYtype();
|
2018-05-02 12:31:21 +02:00
|
|
|
#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[]);
|
2018-09-12 22:51:15 +02:00
|
|
|
static int str2int (const FString&);
|
2018-05-02 12:31:21 +02:00
|
|
|
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[]);
|
2018-10-09 16:04:21 +02:00
|
|
|
static char* secDA_Analysis_65 (char[]);
|
2018-09-16 19:33:40 +02:00
|
|
|
static char* secDA_Analysis_67 (char[]);
|
2018-05-02 12:31:21 +02:00
|
|
|
static char* secDA_Analysis_77 (char[]);
|
|
|
|
static char* secDA_Analysis_82 (char[]);
|
|
|
|
static char* secDA_Analysis_83 (char[]);
|
2018-09-14 22:42:56 +02:00
|
|
|
static char* secDA_Analysis_84 (char[]);
|
2018-05-02 12:31:21 +02:00
|
|
|
static char* secDA_Analysis_85 (char[]);
|
2018-10-09 16:04:21 +02:00
|
|
|
static char* secDA_Analysis_vte (char[]);
|
2018-05-02 12:31:21 +02:00
|
|
|
|
|
|
|
// Data Members
|
|
|
|
static char termtype[256];
|
2018-09-16 19:33:40 +02:00
|
|
|
static char ttytypename[256];
|
2018-05-02 12:31:21 +02:00
|
|
|
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;
|
2018-10-01 22:27:54 +02:00
|
|
|
static FTermData* fterm_data;
|
2018-05-02 12:31:21 +02:00
|
|
|
static terminalType terminal_type;
|
|
|
|
|
|
|
|
static struct colorEnv
|
|
|
|
{
|
|
|
|
void setDefault()
|
|
|
|
{
|
2018-12-10 01:48:26 +01:00
|
|
|
string1 = nullptr;
|
|
|
|
string2 = nullptr;
|
|
|
|
string3 = nullptr;
|
|
|
|
string4 = nullptr;
|
|
|
|
string5 = nullptr;
|
|
|
|
string6 = nullptr;
|
|
|
|
string7 = nullptr;
|
2018-05-02 12:31:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
char* string1;
|
|
|
|
char* string2;
|
|
|
|
char* string3;
|
|
|
|
char* string4;
|
|
|
|
char* string5;
|
|
|
|
char* string6;
|
2018-09-18 06:04:27 +02:00
|
|
|
char* string7;
|
2018-05-02 12:31:21 +02:00
|
|
|
} 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
|
2018-08-09 00:04:00 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline const char* FTermDetection::getClassName() const
|
|
|
|
{ return "FTermDetection"; }
|
|
|
|
|
2018-05-02 12:31:21 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline char* FTermDetection::getTermType()
|
|
|
|
{ return termtype; }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
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
|
|
|
|
|
2018-05-27 19:43:18 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline bool FTermDetection::canDisplay256Colors()
|
|
|
|
{ return color256; }
|
|
|
|
|
2018-05-02 12:31:21 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
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::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; }
|
|
|
|
|
2018-09-14 22:42:56 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline bool FTermDetection::isSunTerminal()
|
|
|
|
{ return terminal_type.sun_con; }
|
|
|
|
|
2018-05-02 12:31:21 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
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::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; }
|
|
|
|
|
2018-09-14 22:42:56 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline void FTermDetection::setSunTerminal (bool on)
|
|
|
|
{ terminal_type.sun_con = on; }
|
|
|
|
|
2018-05-02 12:31:21 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
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; }
|
|
|
|
|
2018-09-20 23:59:01 +02:00
|
|
|
} // namespace finalcut
|
|
|
|
|
2018-05-02 12:31:21 +02:00
|
|
|
#endif // FTERMDETECTION_H
|