FTXUI  5.0.0
C++ functional terminal UI.
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 
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 
29 Dimensions& 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__)
62 #endif
63 
64  std::string COLORTERM = Safe(std::getenv("COLORTERM")); // NOLINT
65  if (Contains(COLORTERM, "24bit") || Contains(COLORTERM, "truecolor")) {
67  }
68 
69  std::string TERM = Safe(std::getenv("TERM")); // NOLINT
70  if (Contains(COLORTERM, "256") || Contains(TERM, "256")) {
72  }
73 
74 #if defined(FTXUI_MICROSOFT_TERMINAL_FALLBACK)
75  // Microsoft terminals do not properly declare themselve 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()) {
81  }
82 #endif
83 
85 }
86 
87 } // namespace
88 
89 namespace Terminal {
90 
91 /// @brief Get the terminal size.
92 /// @return The terminal size.
93 /// @ingroup screen
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
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
141  g_cached = true;
142  g_cached_supported_color = color;
143 }
144 
145 } // namespace Terminal
146 } // namespace ftxui
void SetColorSupport(Color color)
Override terminal color support in case auto-detection fails.
Definition: terminal.cpp:140
void SetFallbackSize(const Dimensions &fallbackSize)
Override terminal size in case auto-detection fails.
Definition: terminal.cpp:124
Dimensions Size()
Get the terminal size.
Definition: terminal.cpp:94
Color ColorSupport()
Get the color support of the terminal.
Definition: terminal.cpp:130
Decorator color(Color)
Decorate using a foreground color.
Definition: color.cpp:110