finalcut/src/ftermdetection.cpp

1021 lines
27 KiB
C++

/***********************************************************************
* ftermdetection.cpp - Detection of the terminal type *
* *
* This file is part of the Final Cut widget toolkit *
* *
* Copyright 2018-2020 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/>. *
***********************************************************************/
#if defined(__CYGWIN__)
#include "final/fconfig.h" // includes _GNU_SOURCE for fd_set
#endif
#include "final/emptyfstring.h"
#include "final/fc.h"
#include "final/fsystem.h"
#include "final/fterm.h"
#include "final/ftermdata.h"
#include "final/ftermdetection.h"
#include "final/ftermios.h"
#include "final/ftypes.h"
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(UNIT_TEST)
#include "final/ftermfreebsd.h"
#endif
#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(UNIT_TEST)
#include "final/ftermopenbsd.h"
#endif
namespace finalcut
{
// static class attributes
FTermDetection::FTerminalType FTermDetection::terminal_type{};
FTermDetection::colorEnv FTermDetection::color_env{};
FTermDetection::secondaryDA FTermDetection::secondary_da{};
FTermData* FTermDetection::fterm_data{nullptr};
FSystem* FTermDetection::fsystem{nullptr};
char FTermDetection::termtype[256]{};
char FTermDetection::ttytypename[256]{};
bool FTermDetection::decscusr_support{};
bool FTermDetection::terminal_detection{};
bool FTermDetection::color256{};
const FString* FTermDetection::answer_back{nullptr};
const FString* FTermDetection::sec_da{nullptr};
int FTermDetection::gnome_terminal_id{};
#if DEBUG
char FTermDetection::termtype_256color[256]{};
char FTermDetection::termtype_Answerback[256]{};
char FTermDetection::termtype_SecDA[256]{};
#endif // DEBUG
//----------------------------------------------------------------------
// 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;
// Set default ttytype file
std::strncpy (ttytypename, C_STR("/etc/ttytype"), sizeof(ttytypename));
ttytypename[sizeof(ttytypename) - 1] = '\0';
}
//----------------------------------------------------------------------
FTermDetection::~FTermDetection() // destructor
{
deallocation();
}
// public methods of FTermDetection
//----------------------------------------------------------------------
#if DEBUG
const FString& FTermDetection::getAnswerbackString()
{
return ( answer_back ) ? *answer_back : fc::emptyFString::get();
}
//----------------------------------------------------------------------
const FString& FTermDetection::getSecDAString()
{
return ( sec_da ) ? *sec_da : fc::emptyFString::get();
}
#endif
//----------------------------------------------------------------------
void FTermDetection::setTtyTypeFileName (const char ttytype_filename[])
{
if ( ! ttytype_filename )
return;
std::strncpy (ttytypename, ttytype_filename, sizeof(ttytypename));
ttytypename[sizeof(ttytypename) - 1] = '\0';
}
//----------------------------------------------------------------------
void FTermDetection::detect()
{
fterm_data = FTerm::getFTermData();
fsystem = FTerm::getFSystem();
deallocation();
// 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::deallocation()
{
if ( sec_da )
delete sec_da;
if ( answer_back )
delete answer_back;
}
//----------------------------------------------------------------------
void FTermDetection::getSystemTermType()
{
// Import the untrusted environment variable TERM
const char* const& term_env = std::getenv(C_STR("TERM"));
const char* termfilename = fterm_data->getTermFileName();
if ( term_env )
{
// Save name in termtype
std::strncpy (termtype, term_env, sizeof(termtype));
termtype[sizeof(termtype) - 1] = '\0';
return;
}
else if ( *termfilename ) // 1st fallback: use the teminal file name
{
if ( getTTYtype() ) // Look into /etc/ttytype
return;
#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"), sizeof(termtype));
termtype[sizeof(termtype) - 1] = '\0';
}
//----------------------------------------------------------------------
bool 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* termfilename = fterm_data->getTermFileName();
const char* term_basename = std::strrchr(termfilename, '/');
if ( term_basename == nullptr )
term_basename = termfilename;
else
term_basename++;
std::FILE* fp{};
char str[BUFSIZ]{};
if ( ! fsystem )
return false;
if ( (fp = fsystem->fopen(ttytypename, "r")) == nullptr )
return false;
// Read and parse the file
while ( fgets(str, sizeof(str) - 1, fp) != nullptr )
{
const char* type{nullptr}; // nullptr == not found
const char* name{nullptr};
char* p = str;
while ( *p )
{
if ( std::isspace(uChar(*p)) )
*p = '\0';
else if ( type == nullptr )
type = p;
else if ( name == nullptr && p != str && p[-1] == '\0' )
name = p;
p++;
}
if ( type != nullptr && name != nullptr && ! std::strcmp(name, term_basename) )
{
// Save name in termtype
std::strncpy (termtype, type, sizeof(termtype));
termtype[sizeof(termtype) - 1] = '\0';
fsystem->fclose(fp);
return true;
}
}
fsystem->fclose(fp);
return false;
}
#if F_HAVE_GETTTYNAM
//----------------------------------------------------------------------
bool FTermDetection::getTTYSFileEntry()
{
// Analyse /etc/ttys and get the term name
// get term basename
const char* termfilename = fterm_data->getTermFileName();
const char* term_basename = std::strrchr(termfilename, '/');
if ( term_basename == nullptr )
term_basename = termfilename;
else
term_basename++;
const struct ttyent* ttys_entryt;
ttys_entryt = getttynam(term_basename);
if ( ttys_entryt )
{
const char* type = ttys_entryt->ty_type;
if ( type != nullptr )
{
// Save name in termtype
std::strncpy (termtype, type, sizeof(termtype));
termtype[sizeof(termtype) - 1] = '\0';
endttyent();
return true;
}
}
endttyent();
return false;
}
#endif // F_HAVE_GETTTYNAM
//----------------------------------------------------------------------
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;
}
// mlterm
if ( std::strncmp(termtype, "mlterm", 6) == 0 )
terminal_type.mlterm = true;
// screen/tmux
if ( std::strncmp(termtype, "screen", 6) == 0 )
{
terminal_type.screen = true;
const char* tmux = std::getenv("TMUX");
if ( tmux && std::strlen(tmux) != 0 )
terminal_type.tmux = 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{nullptr};
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, sizeof(termtype));
termtype[sizeof(termtype) - 1] = '\0';
}
}
//----------------------------------------------------------------------
char* FTermDetection::init_256colorTerminal()
{
char* new_termtype{nullptr};
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
, sizeof(termtype_256color) );
termtype_256color[sizeof(termtype_256color) - 1] = '\0';
}
#endif // DEBUG
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");
color_env.string7 = std::getenv("COLORFGBG");
if ( color_env.string1 != nullptr )
return true;
if ( color_env.string2 != nullptr )
return true;
if ( color_env.string3 != nullptr )
return true;
if ( color_env.string4 != nullptr )
return true;
if ( color_env.string5 != nullptr )
return true;
if ( color_env.string6 != nullptr )
return true;
if ( color_env.string7 != nullptr )
return true;
return false;
}
//----------------------------------------------------------------------
char* FTermDetection::termtype_256color_quirks()
{
char* new_termtype{nullptr};
if ( color_env.string2
|| (color_env.string1
&& std::strncmp(color_env.string1, "gnome-terminal", 14) == 0) )
{
terminal_type.gnome_terminal = true;
// Each gnome-terminal should be able to use 256 colors
color256 = true;
if ( ! isScreenTerm() )
return (new_termtype = C_STR("gnome-256color"));
}
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");
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");
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;
new_termtype = C_STR("konsole-256color");
}
if ( color_env.string3 && std::strlen(color_env.string3) > 0 )
decscusr_support = true;
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(255).isEmpty() )
{
color256 = true;
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 (FColor color)
{
FString color_str{""};
fd_set ifds{};
struct timeval tv{};
const int stdin_no = FTermios::getStdIn();
// get color
std::fprintf (stdout, OSC "4;%hu;?" BEL, color);
std::fflush (stdout);
char temp[512]{};
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, nullptr, nullptr, &tv) > 0 )
{
if ( std::scanf("\033]4;%10hu;%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 << bad_alloc_str << ex.what() << std::endl;
return nullptr;
}
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
, sizeof(termtype_Answerback) - 1);
termtype_Answerback[sizeof(termtype_Answerback) - 1] = '\0';
}
#endif // DEBUG
return new_termtype;
}
//----------------------------------------------------------------------
const FString FTermDetection::getAnswerbackMsg()
{
FString answerback{""};
fd_set ifds{};
struct timeval tv{};
char temp[10]{};
const 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, nullptr, nullptr, &tv) > 0 )
if ( std::fgets (temp, sizeof(temp) - 1, stdin) != nullptr )
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 << bad_alloc_str << 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
const FStringList sec_da_list = temp.split(';');
const 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
secondary_da.terminal_id_type = str2int(sec_da_components[0]);
// Read the terminal (firmware) version
secondary_da.terminal_id_version = str2int(sec_da_components[1]);
// Read the terminal hardware option
secondary_da.terminal_id_hardware = str2int(sec_da_components[2]);
char* new_termtype = secDA_Analysis(current_termtype);
#if DEBUG
if ( new_termtype )
{
std::strncpy (termtype_SecDA, new_termtype, sizeof(termtype_SecDA));
termtype_SecDA[sizeof(termtype_SecDA) - 1] = '\0';
}
#endif // DEBUG
return new_termtype;
}
//----------------------------------------------------------------------
int FTermDetection::str2int (const FString& s)
{
if ( ! s )
return -1;
try
{
return s.toInt();
}
catch (const std::exception&)
{
return -1;
}
}
//----------------------------------------------------------------------
const FString FTermDetection::getSecDA()
{
FString sec_da_str{""};
int a{0};
int b{0};
int c{0};
const int stdin_no{FTermios::getStdIn()};
const int stdout_no{FTermios::getStdOut()};
fd_set ifds{};
struct timeval tv{};
// Get the secondary device attributes
const ssize_t ret = write(stdout_no, SECDA, std::strlen(SECDA));
if ( ret == -1 )
return sec_da_str;
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, nullptr, nullptr, &tv) == 1
&& 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
break;
case 65: // DEC VT525
new_termtype = secDA_Analysis_65(current_termtype);
break;
case 67: // Cygwin
new_termtype = secDA_Analysis_67(current_termtype);
break;
case 77: // mintty
new_termtype = secDA_Analysis_77(current_termtype);
break;
case 82: // rxvt
new_termtype = secDA_Analysis_82();
break;
case 83: // screen
new_termtype = secDA_Analysis_83(current_termtype);
break;
case 84: // tmux
new_termtype = secDA_Analysis_84(current_termtype);
break;
case 85: // rxvt-unicode
new_termtype = secDA_Analysis_85();
break;
default:
break;
}
// Correct false assumptions
if ( isGnomeTerminal()
&& secondary_da.terminal_id_type != 1
&& secondary_da.terminal_id_type != 65 )
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__) || defined(UNIT_TEST)
if ( FTermFreeBSD::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;
new_termtype = secDA_Analysis_vte(new_termtype);
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__) || defined(UNIT_TEST)
if ( secondary_da.terminal_id_version == 20
&& FTermOpenBSD::isBSDConsole() )
{
// 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 // defined(__NetBSD__) || defined(__OpenBSD__) || defined(UNIT_TEST)
return new_termtype;
}
//----------------------------------------------------------------------
inline char* FTermDetection::secDA_Analysis_32 (const char[])
{
// Terminal ID 32 - Tera Term
terminal_type.tera_term = true;
char* new_termtype = C_STR("teraterm");
return new_termtype;
}
//----------------------------------------------------------------------
inline char* FTermDetection::secDA_Analysis_65 (char current_termtype[])
{
// Terminal ID 65 - DEC VT525
char* new_termtype = current_termtype;
new_termtype = secDA_Analysis_vte(new_termtype);
return new_termtype;
}
//----------------------------------------------------------------------
inline char* FTermDetection::secDA_Analysis_67 (const char[])
{
// Terminal ID 67 - cygwin
terminal_type.cygwin = true;
char* new_termtype = C_STR("cygwin");
std::fflush(stdout);
return new_termtype;
}
//----------------------------------------------------------------------
inline char* FTermDetection::secDA_Analysis_77 (const char[])
{
// Terminal ID 77 - mintty
terminal_type.mintty = true;
decscusr_support = true;
char* new_termtype = C_STR("xterm-256color");
std::fflush(stdout);
return new_termtype;
}
//----------------------------------------------------------------------
inline char* FTermDetection::secDA_Analysis_82()
{
// Terminal ID 82 - rxvt
char* new_termtype{};
terminal_type.rxvt = true;
if ( std::strncmp(termtype, "rxvt-cygwin-native", 18) == 0 )
new_termtype = C_STR("rxvt-16color");
else
new_termtype = C_STR("rxvt");
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_84 (char current_termtype[])
{
// Terminal ID 84 - tmux
char* new_termtype = current_termtype;
terminal_type.screen = true;
terminal_type.tmux = true;
return new_termtype;
}
//----------------------------------------------------------------------
inline char* FTermDetection::secDA_Analysis_85()
{
// Terminal ID 85 - rxvt-unicode
char* new_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;
}
//----------------------------------------------------------------------
inline char* FTermDetection::secDA_Analysis_vte (char current_termtype[])
{
// VTE terminal library
// (Since VTE ) the terminal ID has changed from 1 to 65)
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;
}
} // namespace finalcut