FINAL CUT
fterm.h
1 /***********************************************************************
2 * fterm.h - Base class for terminal control *
3 * *
4 * This file is part of the FINAL CUT widget toolkit *
5 * *
6 * Copyright 2012-2026 Markus Gans *
7 * *
8 * FINAL CUT is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU Lesser General Public License as *
10 * published by the Free Software Foundation; either version 3 of *
11 * the License, or (at your option) any later version. *
12 * *
13 * FINAL CUT is distributed in the hope that it will be useful, but *
14 * WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this program. If not, see *
20 * <http://www.gnu.org/licenses/>. *
21 ***********************************************************************/
22 
23 /* Base class
24  * ══════════
25  *
26  * ▕▔▔▔▔▔▔▔▏1 1▕▔▔▔▔▔▔▔▔▔▔▏
27  * ▕ FTerm ▏-┬- - - -▕ FTermios ▏
28  * ▕▁▁▁▁▁▁▁▏ : ▕▁▁▁▁▁▁▁▁▁▁▏
29  * :
30  * : 1▕▔▔▔▔▔▔▔▔▔▔▏
31  * :- - - -▕ FTermcap ▏
32  * : ▕▁▁▁▁▁▁▁▁▁▁▏
33  * :
34  * : 1▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏
35  * :- - - -▕ FTermcapQuirks ▏
36  * : ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏
37  * :
38  * : 1▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏
39  * :- - - -▕ FTermDetection ▏
40  * : ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏
41  * :
42  * : 1▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏
43  * :- - - -▕ FTermXTerminal ▏
44  * : ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏
45  * :
46  * : 1▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏
47  * :- - - -▕ FTermLinux ▏
48  * : ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏
49  * :
50  * : 1▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏
51  * :- - - -▕ FTermFreeBSD ▏
52  * : ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏
53  * :
54  * : 1▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏
55  * :- - - -▕ FTermOpenBSD ▏
56  * : ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏
57  * :
58  * : 1▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏
59  * :- - - -▕ FColorPalette ▏
60  * : ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏
61  * :
62  * : 1▕▔▔▔▔▔▔▔▔▔▔▔▏
63  * :- - - -▕ FOptiAttr ▏
64  * : ▕▁▁▁▁▁▁▁▁▁▁▁▏
65  * :
66  * : 1▕▔▔▔▔▔▔▔▔▔▔▔▏
67  * :- - - -▕ FOptiMove ▏
68  * : ▕▁▁▁▁▁▁▁▁▁▁▁▏
69  * :
70  * : 1▕▔▔▔▔▔▔▔▔▔▔▔▏
71  * :- - - -▕ FKeyboard ▏
72  * : ▕▁▁▁▁▁▁▁▁▁▁▁▏
73  * :
74  * : 1▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏
75  * :- - - -▕ FMouseControl ▏
76  * : ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏
77  * :
78  * : *▕▔▔▔▔▔▔▔▔▔▏
79  * :- - - -▕ FString ▏
80  * : ▕▁▁▁▁▁▁▁▁▁▏
81  * :
82  * : *▕▔▔▔▔▔▔▔▔▏
83  * :- - - -▕ FPoint ▏
84  * : ▕▁▁▁▁▁▁▁▁▏
85  * :
86  * : *▕▔▔▔▔▔▔▔▏
87  * └- - - -▕ FRect ▏
88  * ▕▁▁▁▁▁▁▁▏
89  */
90 
91 #ifndef FTERM_H
92 #define FTERM_H
93 
94 #if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
95  #error "Only <final/final.h> can be included directly."
96 #endif
97 
98 #include "final/fconfig.h"
99 
100 #include <sys/ioctl.h>
101 #include <sys/stat.h>
102 
103 #include <fcntl.h>
104 #include <langinfo.h>
105 
106 #if defined(F_HAVE_GETTTYNAM) && defined(F_HAVE_TTYENT_H)
107  #include <ttyent.h>
108 #endif
109 
110 #include <clocale>
111 #include <cmath>
112 #include <csignal>
113 
114 #include <functional>
115 #include <memory>
116 #include <string>
117 #include <utility>
118 #include <vector>
119 
120 #include "final/fc.h"
121 #include "final/output/fcolorpalette.h"
122 #include "final/output/tty/ftermcap.h"
123 #include "final/output/tty/ftermdata.h"
124 #include "final/output/tty/fterm_functions.h"
125 #include "final/util/fstring.h"
126 #include "final/util/fsystem.h"
127 
128 namespace finalcut
129 {
130 
131 // class forward declaration
132 class FColorPalette;
133 class FPoint;
134 class FStartOptions;
135 class FSize;
136 class FString;
137 class FVTermBuffer;
138 
139 
140 //----------------------------------------------------------------------
141 // class FTerm
142 //----------------------------------------------------------------------
143 
144 class FTerm final
145 {
146  public:
147  // Using-declaration
148  using FSetPalette = FColorPalette::FSetPalette;
149 
150  // Constructor
151  FTerm();
152 
153  // Disable copy constructor
154  FTerm (const FTerm&) = delete;
155 
156  // Disable move constructor
157  FTerm (FTerm&&) noexcept = delete;
158 
159  // Destructor
160  ~FTerm();
161 
162  // Disable copy assignment operator (=)
163  auto operator = (const FTerm&) -> FTerm& = delete;
164 
165  // Disable move assignment operator (=)
166  auto operator = (FTerm&&) noexcept -> FTerm& = delete;
167 
168  // Accessors
169  static auto getClassName() -> FString;
170  static auto getLineNumber() -> std::size_t;
171  static auto getColumnNumber() -> std::size_t;
172  static auto getKeyName (FKey) -> FString;
173  auto getCharSubstitutionMap() & -> FCharSubstitution&;
174  static auto getTTYFileDescriptor() -> int;
175  static auto getTermType() -> std::string;
176  static auto getTermFileName() -> std::string;
177  static auto getTabstop() -> int;
178  static auto getMaxColor() -> int;
179 
180  // Predicates
181  static auto isRaw() -> bool;
182  static auto hasUTF8() -> bool;
183  static auto isMonochron() -> bool;
184  static auto isNewFont() -> bool;
185  static auto isInitialized() -> bool;
186  static auto isCursorHideable() -> bool;
187  static auto isEncodable (const wchar_t&) -> bool;
188  static auto hasChangedTermSize() -> bool;
189  static auto hasShadowCharacter() -> bool;
190  static auto hasHalfBlockCharacter() -> bool;
191  static auto hasAlternateScreen() -> bool;
192  static auto canChangeColorPalette() -> bool;
193 
194  // Mutators
195  static void setFSystem (std::unique_ptr<FSystem>&);
196  static void setTermType (const std::string&);
197  static void setInsertCursor (bool = true);
198  static void unsetInsertCursor();
199  static void redefineDefaultColors (bool = true);
200  static void setDblclickInterval (const uInt64);
201  static void useAlternateScreen (bool = true);
202  static void setUTF8 (bool = true);
203  static void unsetUTF8();
204 
205  // Methods
206  static auto setVGAFont() -> bool;
207  static auto setNewFont() -> bool;
208  static auto resetFont() -> bool;
209  static auto openConsole() -> int;
210  static auto closeConsole() -> int;
211  static auto moveCursor (int, int, int, int) -> FTermcap::TermcapString;
212  static auto cursorsVisibility (bool = true) -> FTermcap::TermcapString;
213  static void detectTermSize();
214  static void setTermSize (const FSize&);
215  static void setTermTitle (const FString&);
216  static void setKDECursor (KdeKonsoleCursorShape);
217  static void saveColorMap();
218  static void resetColorMap();
219  static void clearTerminalAttributes();
220  static void setPalette (FColor, int, int, int);
221  static void setBeep (int, int);
222  static void resetBeep();
223  static void beep();
224 
225  static void setEncoding (Encoding);
226  static auto getEncodingString() -> std::string;
227  static auto charEncode (const wchar_t&) -> wchar_t;
228  static auto charEncode (const wchar_t&, const Encoding&) -> wchar_t;
229 
230  static auto scrollTermForward() -> bool;
231  static auto scrollTermReverse() -> bool;
232 
233  template <typename... Args>
234  static void paddingPrintf (Args&&...);
235  static void paddingPrint (const FTermcap::TermcapString&, int = 1);
236  static void paddingPrint (const char*, uInt32, int = 1);
237  static void paddingPrint (const char*, int = 1);
238  static void stringPrint (const char*, uInt32);
239 
240  void initTerminal();
241  static void initScreenSettings();
242  static void changeTermSizeFinished();
243 
244  private:
245  // Methods
246  static auto getStartOptions() -> FStartOptions&;
247  static void init_global_values();
248  static void init_terminal_device_path();
249  static void oscPrefix();
250  static void oscPostfix();
251  static void init_alt_charset();
252  static void init_pc_charset();
253  static auto configEnterPcCharsetMode() -> bool;
254  static auto configExitPcCharsetMode() -> bool;
255  static void init_cygwin_charmap();
256  static void updatePCEncodingForCygwin();
257  static void updateCharMappingForCygwin();
258  static void init_teraterm_charmap();
259  static void init_fixed_max_color();
260  static void init_termcap();
261  static void init_quirks();
262  static void init_optiMove();
263  static void init_optiAttr();
264  static auto init_font() -> bool;
265  static void init_locale();
266  static auto init_xterm_locale (const char*) -> const char*;
267  static auto init_tera_term_locale (const char*) -> const char*;
268  static auto init_kterm_locale (const char*) -> const char*;
269  static auto init_sun_locale (const char*) -> const char*;
270  static auto init_locale_if_not_found (const char*) -> const char*;
271  static void init_encoding();
272  static void init_encoding_set();
273  static void init_term_encoding();
274  static void init_individual_term_encoding();
275  static void init_force_vt100_encoding();
276  static void init_utf8_without_alt_charset();
277  static void init_tab_quirks();
278  static void init_captureFontAndTitle();
279  static auto hasNoFontSettingOption() -> bool;
280  static auto canSetTerminalFont() -> bool;
281  static void setInsertCursorStyle();
282  static void setOverwriteCursorStyle();
283  static auto enableCursor() -> FTermcap::TermcapString;
284  static auto disableCursor() -> FTermcap::TermcapString;
285  static void enableMouse();
286  static void disableMouse();
287  static void enableApplicationEscKey();
288  static void disableApplicationEscKey();
289  static void enableKeypad();
290  static void disableKeypad();
291  static void enableAlternateCharset();
292  static void useAlternateScreenBuffer();
293  static void useNormalScreenBuffer();
294  void init();
295  auto init_terminal() const -> bool;
296  void initOSspecifics() const;
297  void initTermspecifics() const;
298  void initBaudRate() const;
299  void finish() const;
300  void finishOSspecifics() const;
301  void finish_encoding() const;
302  static void printExitMessage();
303  static void terminalSizeChange();
304  [[noreturn]] static void processTermination (int);
305  static void setSignalHandler();
306  static void resetSignalHandler();
307  static void signal_handler (int);
308 };
309 
310 
311 // FTerm inline functions
312 //----------------------------------------------------------------------
313 inline auto FTerm::getClassName() -> FString
314 { return "FTerm"; }
315 
316 //----------------------------------------------------------------------
317 inline auto FTerm::getTabstop() -> int
318 { return FTermcap::tabstop; }
319 
320 //----------------------------------------------------------------------
321 inline auto FTerm::getMaxColor() -> int
322 { return FTermcap::max_color; }
323 
324 //----------------------------------------------------------------------
325 inline auto FTerm::hasUTF8() -> bool
326 {
327  static const auto& fterm_data = FTermData::getInstance();
328  return fterm_data.hasUTF8Console();
329 }
330 
331 //----------------------------------------------------------------------
332 inline auto FTerm::isMonochron() -> bool
333 {
334  static const auto& fterm_data = FTermData::getInstance();
335  return fterm_data.isMonochron();
336 }
337 
338 //----------------------------------------------------------------------
339 inline auto FTerm::isNewFont() -> bool
340 {
341  static const auto& fterm_data = FTermData::getInstance();
342  return fterm_data.isNewFont();
343 }
344 
345 //----------------------------------------------------------------------
346 inline void FTerm::setFSystem (std::unique_ptr<FSystem>& fsystem)
347 {
348  FSystem::getInstance().swap(fsystem);
349 }
350 
351 //----------------------------------------------------------------------
352 inline void FTerm::unsetInsertCursor()
353 { setInsertCursor(false); }
354 
355 //----------------------------------------------------------------------
356 inline void FTerm::unsetUTF8()
357 { setUTF8(false); }
358 
359 //----------------------------------------------------------------------
360 template <typename... Args>
361 inline void FTerm::paddingPrintf (Args&&... args)
362 {
363  const int size = std::snprintf (nullptr, 0, args...);
364 
365  if ( size <= 0 )
366  return;
367 
368  std::string buffer{};
369  auto buffer_size = std::size_t(size) + 1;
370  buffer.resize(buffer_size);
371  std::snprintf ( &*buffer.begin(), buffer_size
372  , std::forward<Args>(args)... );
373  buffer_size--;
374  buffer.resize(buffer_size);
375  paddingPrint (buffer.c_str(), uInt32(size), 1);
376 }
377 
378 //----------------------------------------------------------------------
379 inline void FTerm::initTerminal()
380 { init(); }
381 
382 } // namespace finalcut
383 
384 //----------------------------------------------------------------------
385 inline auto operator << (std::ostream& os, finalcut::UniChar c) -> std::ostream&
386 {
387  static const auto& data = finalcut::FTermData::getInstance();
388 
389  if ( data.getTerminalEncoding() == finalcut::Encoding::UTF8 )
390  {
391  std::array<char, 4> buf{};
392  const uInt32 len = finalcut::UTF8::encode(wchar_t(c), buf);
393  return os.write(&buf[0], len);
394  }
395 
396  return os << static_cast<char>(uChar(c));
397 }
398 
399 //----------------------------------------------------------------------
400 inline auto operator << (std::wostream& os, finalcut::UniChar c) -> std::wostream&
401 {
402  return os << static_cast<wchar_t>(c);
403 }
404 
405 #endif // FTERM_H
Definition: ftermcap.h:72
Definition: ftermdata.h:58
Definition: class_template.cpp:25
Definition: fsize.h:55
Definition: fstartoptions.h:52
Definition: fstring.h:82
Definition: fterm.h:144