FINAL CUT
ftermoutput.h
1 /***********************************************************************
2 * ftermoutput.h - Implements the terminal output *
3 * *
4 * This file is part of the FINAL CUT widget toolkit *
5 * *
6 * Copyright 2021-2024 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 /* Standalone class
24  * ════════════════
25  *
26  * ▕▔▔▔▔▔▔▔▔▔▏
27  * ▕ FOutput ▏
28  * ▕▁▁▁▁▁▁▁▁▁▏
29  * ▲
30  * │
31  * ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▏
32  * ▕ FTermOutput ▏
33  * ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▏
34  */
35 
36 #ifndef FTERMOUTPUT_H
37 #define FTERMOUTPUT_H
38 
39 #if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
40  #error "Only <final/final.h> can be included directly."
41 #endif
42 
43 #include <memory>
44 #include <string>
45 #include <tuple>
46 #include <utility>
47 
48 #include "final/output/foutput.h"
49 #include "final/output/tty/fterm.h"
50 
51 namespace finalcut
52 {
53 
54 // class forward declaration
55 class FStartOptions;
56 class FTermData;
57 template <typename T, std::size_t Capacity>
59 
60 //----------------------------------------------------------------------
61 // class FTermOutput
62 //----------------------------------------------------------------------
63 
64 class FTermOutput final : public FOutput
65 {
66  public:
67  // Constructor
68  FTermOutput() = default;
69 
70  explicit FTermOutput (const FVTerm&);
71 
72  // Destructor
73  ~FTermOutput() noexcept override;
74 
75  // Accessors
76  auto getClassName() const -> FString override;
77  auto getFTerm() & -> FTerm&;
78  auto getColumnNumber() const -> std::size_t override;
79  auto getLineNumber() const -> std::size_t override;
80  auto getTabstop() const -> int override;
81  auto getMaxColor() const -> int override;
82  auto getEncoding() const -> Encoding override;
83  auto getKeyName (FKey) const -> FString override;
84 
85  // Mutators
86  void setCursor (FPoint) override;
87  void setCursor (CursorMode) override;
88  void hideCursor (bool = true) override;
89  void showCursor() override;
90  void setTerminalSize (FSize) override;
91  auto setVGAFont() -> bool override;
92  auto setNewFont() -> bool override;
93  void setNonBlockingRead (bool = true) override;
94 
95  // Inquiries
96  auto isCursorHideable() const -> bool override;
97  auto isMonochron() const -> bool override;
98  auto isNewFont() const -> bool override;
99  auto isEncodable (const wchar_t&) const -> bool override;
100  auto isFlushTimeout() const -> bool override;
101  auto hasTerminalResized() const -> bool override;
102  auto allowsTerminalSizeManipulation() const -> bool override;
103  auto canChangeColorPalette() const -> bool override;
104  auto hasHalfBlockCharacter() const -> bool override;
105  auto hasShadowCharacter() const -> bool override;
106  auto areMetaAndArrowKeysSupported() const -> bool override;
107 
108  // Methods
109  void initTerminal (FVTerm::FTermArea*) override;
110  void finishTerminal() override;
111  auto updateTerminal() -> bool override;
112  void detectTerminalSize() override;
113  void commitTerminalResize() override;
114  void initScreenSettings() override;
115  auto scrollTerminalForward() -> bool override;
116  auto scrollTerminalReverse() -> bool override;
117  void clearTerminalAttributes() override;
118  void clearTerminalState() override;
119  auto clearTerminal (wchar_t = L' ') -> bool override;
120  void flush() override;
121  void beep() const override;
122 
123  private:
124  // Constants
125  struct FTermControl
126  {
127  std::string string;
128  };
129 
130  // Enumerations
131  enum class PrintState
132  {
133  NothingPrinted,
134  RepeatCharacterPrinted,
135  WhitespacesPrinted,
136  LineCompletelyPrinted
137  };
138 
139  enum class Repetition
140  {
141  ASCII,
142  UTF8,
143  NotOptimized
144  };
145 
146  enum class OutputType : uInt8 // Output data type of the terminal
147  {
148  String,
149  Control
150  };
151 
152  enum class CursorMoved { No, Yes };
153 
154  struct OutputData
155  {
156  OutputData() = default;
157 
158  OutputData (OutputType t, std::string s)
159  : type{t}
160  , data{std::move(s)}
161  { }
162 
163  OutputType type{OutputType::String};
164  std::string data{};
165  };
166 
167  // Constants
168  // Upper and lower flush limit
169  static constexpr uInt64 MIN_FLUSH_WAIT = 16'667; // 16.6 ms = 60 Hz
170  static constexpr uInt64 MAX_FLUSH_WAIT = 200'000; // 200.0 ms = 5 Hz
171  // Output buffer size
172  static constexpr std::size_t BUFFER_SIZE = 32'768; // 32 KB
173 
174  // Using-declaration
175  using OutputBuffer = FRingBuffer<OutputData, BUFFER_SIZE>;
176 
177  // Accessors
178  auto getFSetPaletteRef() const & -> const FSetPalette& override;
179 
180  // Methods
181  auto getStartOptions() & -> FStartOptions&;
182  auto isInputCursorInsideTerminal() const -> bool;
183  auto isDefaultPaletteTheme() const -> bool override;
184  void redefineColorPalette() override;
185  void restoreColorPalette() override;
186  void init_characterLengths();
187  void init_combined_character();
188  auto canClearToEOL (uInt, uInt) const -> bool;
189  auto canClearLeadingWS (uInt&, uInt) const -> bool;
190  auto canClearTrailingWS (uInt&, uInt) const -> bool;
191  auto skipUnchangedCharacters (uInt&, uInt, uInt) -> bool;
192  void printRange (uInt, uInt, uInt);
193  void replaceNonPrintableFullwidth (uInt, FChar&) const;
194  void printCharacter (uInt&, uInt, bool, FChar&);
195  void printFullWidthCharacter (uInt&, uInt, FChar&);
196  void printFullWidthPaddingCharacter (uInt&, uInt, FChar&);
197  void printHalfCovertFullWidthCharacter (uInt, uInt, FChar&);
198  void printEllipsis (uInt, uInt, FChar&);
199  void skipPaddingCharacter (uInt&, uInt, const FChar&) const;
200  auto eraseCharacters (uInt&, uInt, uInt) -> PrintState;
201  auto repeatCharacter (uInt&, uInt, uInt) -> PrintState;
202  auto countRepetitions (const FChar*, uInt, uInt) const -> uInt;
203  auto canUseEraseCharacters (const FChar&, uInt) const -> bool;
204  auto canUseCharacterRepetitions (const FChar&, uInt) const -> bool;
205  auto getRepetitionType (const FChar&, uInt) const -> Repetition;
206  auto isFullWidthChar (const FChar&) const -> bool;
207  auto isFullWidthPaddingChar (const FChar&) const -> bool;
208  void cursorWrap() const;
209  void adjustCursorPosition (FPoint&) const;
210  auto updateTerminalLine (uInt) -> bool;
211  auto updateTerminalCursor() -> bool;
212  void flushTimeAdjustment();
213  void markAsPrinted (uInt, uInt) const;
214  void markAsPrinted (uInt, uInt, uInt) const;
215  void newFontChanges (FChar&) const;
216  void charsetChanges (FChar&) const;
217  void appendCharacter (FChar&);
218  void appendCharacter_n (FChar&, uInt);
219  void appendChar (FChar&);
220  void appendAttributes (FChar&);
221  void appendLowerRight (FChar&);
222  void characterFilter (FChar&);
223  auto moveCursorLeft() -> CursorMoved;
224  void checkFreeBufferSize();
225  void appendOutputBuffer (const FTermControl&);
226  void appendOutputBuffer (const UniChar&);
227  void appendOutputBuffer (std::string&&);
228 
229  // Data members
230  FTerm fterm{};
231  static FVTerm::FTermArea* vterm;
232  static FTermData* fterm_data;
233  std::shared_ptr<OutputBuffer> output_buffer{};
234  std::shared_ptr<FPoint> term_pos{}; // terminal cursor position
235  TimeValue time_last_flush{};
236  FChar term_attribute{};
237  bool cursor_hideable{false};
238  bool combined_char_support{false};
239  uInt erase_char_length{};
240  uInt repeat_char_length{};
241  uInt clr_bol_length{};
242  uInt clr_eol_length{};
243  uInt cursor_address_length{};
244  uInt64 flush_wait{MIN_FLUSH_WAIT};
245  uInt64 flush_average{MIN_FLUSH_WAIT};
246  uInt64 flush_median{MIN_FLUSH_WAIT};
247 };
248 
249 // FTermOutput inline functions
250 //----------------------------------------------------------------------
251 inline auto FTermOutput::getClassName() const -> FString
252 { return "FTermOutput"; }
253 
254 //----------------------------------------------------------------------
255 inline auto FTermOutput::getFTerm() & -> FTerm&
256 { return fterm; }
257 
258 //----------------------------------------------------------------------
259 inline void FTermOutput::showCursor()
260 { return hideCursor(false); }
261 
262 //----------------------------------------------------------------------
263 inline auto FTermOutput::isCursorHideable() const -> bool
264 { return cursor_hideable; }
265 
266 //----------------------------------------------------------------------
267 inline auto FTermOutput::getFSetPaletteRef() const & -> const FSetPalette&
268 {
269  static const FSetPalette& f = &FTerm::setPalette;
270  return f;
271 }
272 
273 } // namespace finalcut
274 
275 #endif // FTERMOUTPUT_H
276 
Definition: foutput.h:56
Definition: fvterm.h:96
Definition: class_template.cpp:25
Definition: ftermoutput.h:64
Definition: fpoint.h:50
Definition: fsize.h:55
Definition: fstring.h:79
Definition: ftermoutput.h:58
Definition: fvterm.h:373
Definition: fterm.h:143