FTXUI 6.1.9 C++ functional terminal UI.

Loading...
Searching...
No Matches
terminal.cpp
Go to the documentation of this file.
1// Copyright 2020 Arthur Sonzogni. All rights reserved.
2// Use of this source code is governed by the MIT license that can be found in
3// the LICENSE file.
4#include <cstdlib> // for getenv
5#include <string> // for string, allocator
6
7#include "ftxui/screen/terminal.hpp"
8
9#if defined(_WIN32)
10#define WIN32_LEAN_AND_MEAN
11
12#ifndef NOMINMAX
13#define NOMINMAX
14#endif
15
16#include <windows.h>
17#else
18#include <sys/ioctl.h> // for winsize, ioctl, TIOCGWINSZ
19#include <unistd.h> // for STDOUT_FILENO
20#endif
21
22 namespace ftxui {
23
24 namespace {
25
26 bool g_cached = false; // NOLINT
27 Terminal::Color g_cached_supported_color; // NOLINT
28
29Dimensions& FallbackSize() {
30#if defined(__EMSCRIPTEN__)
31 // This dimension was chosen arbitrarily to be able to display:
32 // https://arthursonzogni.com/FTXUI/examples
33 // This will have to be improved when someone has time to implement and need
34 // it.
35 constexpr int fallback_width = 140;
36 constexpr int fallback_height = 43;
37#else
38 // The terminal size in VT100 was 80x24. It is still used nowadays by
39 // default in many terminal emulator. That's a good choice for a fallback
40 // value.
41 constexpr int fallback_width = 80;
42 constexpr int fallback_height = 24;
43#endif
44 static Dimensions g_fallback_size{
45 fallback_width,
46 fallback_height,
47 };
48 return g_fallback_size;
49}
50
51 const char* Safe(const char* c) {
52 return (c != nullptr) ? c : "";
53}
54
55 bool Contains(const std::string& s, const char* key) {
56 return s.find(key) != std::string::npos;
57}
58
59 Terminal::Color ComputeColorSupport() {
60#if defined(__EMSCRIPTEN__)
61 return Terminal::Color::TrueColor;
62#endif
63
64 std::string COLORTERM = Safe(std::getenv("COLORTERM")); // NOLINT
65 if (Contains(COLORTERM, "24bit") || Contains(COLORTERM, "truecolor")) {
66 return Terminal::Color::TrueColor;
67 }
68
69 std::string TERM = Safe(std::getenv("TERM")); // NOLINT
70 if (Contains(COLORTERM, "256") || Contains(TERM, "256")) {
71 return Terminal::Color::Palette256;
72 }
73
74#if defined(FTXUI_MICROSOFT_TERMINAL_FALLBACK)
75 // Microsoft terminals do not properly declare themselves supporting true
76 // colors: https://github.com/microsoft/terminal/issues/1040
77 // As a fallback, assume microsoft terminal are the ones not setting those
78 // variables, and enable true colors.
79 if (TERM.empty() && COLORTERM.empty()) {
80 return Terminal::Color::TrueColor;
81 }
82#endif
83
84 return Terminal::Color::Palette16;
85}
86
87} // namespace
88
89 namespace Terminal {
90
91/// @brief Get the terminal size.
92/// @return The terminal size.
93/// @ingroup screen
94 Dimensions Size() {
95#if defined(__EMSCRIPTEN__)
96 // This dimension was chosen arbitrarily to be able to display:
97 // https://arthursonzogni.com/FTXUI/examples
98 // This will have to be improved when someone has time to implement and need
99 // it.
100 return FallbackSize();
101#elif defined(_WIN32)
102 CONSOLE_SCREEN_BUFFER_INFO csbi;
103
104 if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) {
105 return Dimensions{csbi.srWindow.Right - csbi.srWindow.Left + 1,
106 csbi.srWindow.Bottom - csbi.srWindow.Top + 1};
107 }
108
109 return FallbackSize();
110#else
111 winsize w{};
112 const int status = ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); // NOLINT
113 // The ioctl return value result should be checked. Some operating systems
114 // don't support TIOCGWINSZ.
115 if (w.ws_col == 0 || w.ws_row == 0 || status < 0) {
116 return FallbackSize();
117 }
118 return Dimensions{w.ws_col, w.ws_row};
119#endif
120}
121
122/// @brief Override terminal size in case auto-detection fails
123/// @param fallbackSize Terminal dimensions to fallback to
124 void SetFallbackSize(const Dimensions& fallbackSize) {
125 FallbackSize() = fallbackSize;
126}
127
128/// @brief Get the color support of the terminal.
129/// @ingroup screen
130 Color ColorSupport() {
131 if (!g_cached) {
132 g_cached = true;
133 g_cached_supported_color = ComputeColorSupport();
134 }
135 return g_cached_supported_color;
136}
137
138/// @brief Override terminal color support in case auto-detection fails
139/// @ingroup dom
140 void SetColorSupport(Color color) {
141 g_cached = true;
142 g_cached_supported_color = color;
143}
144
145} // namespace Terminal
146} // namespace ftxui
ftxui::Terminal::SetColorSupport
void SetColorSupport(Color color)
Override terminal color support in case auto-detection fails.
Definition terminal.cpp:140
ftxui::color
Decorator color(Color)
Decorate using a foreground color.
Definition dom/color.cpp:110
ftxui::Terminal::Color
Color
Color is an enumeration that represents the color support of the terminal.
Definition terminal.hpp:23
ftxui::Terminal::Size
Dimensions Size()
Get the terminal size.
Definition terminal.cpp:94
ftxui::Terminal::ColorSupport
Color ColorSupport()
Get the color support of the terminal.
Definition terminal.cpp:130
ftxui::Terminal::TrueColor
@ TrueColor
Definition terminal.hpp:27
ftxui::Terminal::Palette256
@ Palette256
Definition terminal.hpp:26
ftxui::Terminal::Palette16
@ Palette16
Definition terminal.hpp:25
ftxui::Dimensions
Dimensions is a structure that represents the size of the terminal.
Definition terminal.hpp:11
ftxui::Terminal::SetFallbackSize
void SetFallbackSize(const Dimensions &fallbackSize)
Override terminal size in case auto-detection fails.
Definition terminal.cpp:124
ftxui
The FTXUI ftxui:: namespace.
Definition animation.hpp:10
terminal.hpp