FINAL CUT
fvterm.h
1 /***********************************************************************
2 * fvterm.h - Virtual terminal implementation *
3 * *
4 * This file is part of the FINAL CUT widget toolkit *
5 * *
6 * Copyright 2016-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 /* Inheritance diagram
24  * ═══════════════════
25  *
26  * ▕▔▔▔▔▔▔▔▔▔▏1 *▕▔▔▔▔▔▔▔▏
27  * ▕ FVTerm ▏- - -┬- - -▕ FTerm ▏
28  * ▕▁▁▁▁▁▁▁▁▁▏ : ▕▁▁▁▁▁▁▁▏
29  * :
30  * : *▕▔▔▔▔▔▔▔▔▔▏
31  * :- - -▕ FString ▏
32  * : ▕▁▁▁▁▁▁▁▁▁▏
33  * :
34  * : *▕▔▔▔▔▔▔▔▔▏
35  * └- - -▕ FPoint ▏
36  * : ▕▁▁▁▁▁▁▁▁▏
37  * :
38  * : *▕▔▔▔▔▔▔▔▏
39  * └- - -▕ FRect ▏
40  * ▕▁▁▁▁▁▁▁▏
41  */
42 
43 #ifndef FVTERM_H
44 #define FVTERM_H
45 
46 #if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
47  #error "Only <final/final.h> can be included directly."
48 #endif
49 
50 #include <sys/time.h> // need for timeval (cygwin)
51 
52 #include <algorithm>
53 #include <memory>
54 #include <string>
55 #include <tuple>
56 #include <utility>
57 #include <vector>
58 
59 #include "final/fc.h"
60 #include "final/output/tty/fterm_functions.h"
61 #include "final/util/fdata.h"
62 #include "final/util/fpoint.h"
63 #include "final/util/frect.h"
64 #include "final/util/fsize.h"
65 #include "final/util/fstringstream.h"
66 #include "final/vterm/fvtermattribute.h"
67 #include "final/vterm/fvtermbuffer.h"
68 
69 #define F_PREPROC_HANDLER(i,h) \
70  reinterpret_cast<FVTerm*>((i)), \
71  std::bind ( reinterpret_cast<FVTerm::FPreprocessingHandler>((h)) \
72  , reinterpret_cast<FVTerm*>((i)) )
73 
74 namespace finalcut
75 {
76 
77 // class forward declaration
78 class FColorPair;
79 class FOutput;
80 class FSize;
81 class FString;
82 class FStyle;
83 class FVTermBuffer;
84 class FWidget;
85 
86 template <typename FOutputType>
88 {
89  using type = std::remove_cv_t<FOutputType>;
90 };
91 
92 //----------------------------------------------------------------------
93 // class FVTerm
94 //----------------------------------------------------------------------
95 
96 class FVTerm : public FVTermAttribute
97 {
98  public:
99  struct FTermArea; // forward declaration
100  struct FVTermPreprocessing; // forward declaration
101 
103  {
104  uInt xmin; // X-position with the first change
105  uInt xmax; // X-position with the last change
106  uInt trans_count; // Number of transparent characters
107  };
108 
109  // Using-declarations
110  using FVTermAttribute::print;
111  using FCharVector = std::vector<FChar>;
112  using FPreprocessingHandler = void (FVTerm::*)();
113  using FPreprocessingFunction = std::function<void()>;
114  using FPreprocVector = std::vector<std::unique_ptr<FVTermPreprocessing>>;
115  using FVTermList = std::vector<FVTerm*>;
116 
117  // Enumeration
118  enum class TerminalUpdate
119  {
120  Stop, // No terminal refresh
121  Continue, // Resuming terminal refresh
122  Start // Allowing terminal refresh
123  };
124 
125  // Disable copy constructor
126  FVTerm (const FVTerm&) = delete;
127 
128  // Disable move constructor
129  FVTerm (FVTerm&&) noexcept = delete;
130 
131  // Constructor
132  FVTerm();
133 
134  template <typename FOutputType>
135  explicit FVTerm (outputClass<FOutputType>);
136 
137  // Disable copy assignment operator (=)
138  auto operator = (const FVTerm&) -> FVTerm& = delete;
139 
140  // Disable move assignment operator (=)
141  auto operator = (FVTerm&&) noexcept -> FVTerm& = delete;
142 
143  // Destructor
144  ~FVTerm() override;
145 
146  // Overloaded operators
147  template <typename NumT
148  , enable_if_arithmetic_without_char_t<NumT> = nullptr>
149  auto operator << (const NumT&) noexcept -> FVTerm&;
150 
151  template <typename CharT
152  , enable_if_CString_t<CharT> = nullptr>
153  auto operator << (const CharT&) noexcept -> FVTerm&;
154  auto operator << (char) noexcept -> FVTerm&;
155  auto operator << (wchar_t) noexcept -> FVTerm&;
156  auto operator << (const wchar_t*) noexcept -> FVTerm&;
157  auto operator << (const UniChar&) noexcept -> FVTerm&;
158  auto operator << (const std::string&) noexcept -> FVTerm&;
159  auto operator << (const std::wstring&) noexcept -> FVTerm&;
160  auto operator << (const FString&) noexcept -> FVTerm&;
161  auto operator << (FVTermBuffer&) noexcept -> FVTerm&;
162  auto operator << (const FVTermBuffer&) noexcept -> FVTerm&;
163  auto operator << (const FChar&) noexcept -> FVTerm&;
164  auto operator << (const FCharVector&) noexcept -> FVTerm&;
165  auto operator << (const FPoint&) noexcept -> FVTerm&;
166  auto operator << (const FStyle&) noexcept -> FVTerm&;
167  auto operator << (const FColorPair&) noexcept -> FVTerm&;
168 
169  // Accessors
170  auto getClassName() const -> FString override;
171  static auto getFOutput() -> std::shared_ptr<FOutput>;
172  auto getVWin() noexcept -> FTermArea*;
173  auto getVWin() const noexcept -> const FTermArea*;
174  auto getPrintCursor() -> FPoint;
175  static auto getWindowList() -> FVTermList*;
176 
177  // Mutators
178  void setTerminalUpdates (TerminalUpdate) const;
179  void setCursor (const FPoint&) noexcept;
180  void setVWin (std::unique_ptr<FTermArea>&&) noexcept;
181  static void setNonBlockingRead (bool = true);
182  static void unsetNonBlockingRead();
183 
184  // Inquiries
185  static auto isDrawingFinished() noexcept -> bool;
186  static auto isTerminalUpdateForced() noexcept -> bool;
187  static auto areTerminalUpdatesPaused() noexcept -> bool;
188  static auto hasPendingTerminalUpdates() noexcept -> bool;
189  auto hasPreprocessingHandler (const FVTerm*) noexcept -> bool;
190 
191  // Methods
192  virtual void clearArea (wchar_t = L' ');
193  void createVDesktop (const FSize& size) noexcept;
194  void createVTerm (const FSize&) noexcept;
195  void resizeVTerm (const FSize&) const noexcept;
196  void putVTerm() const;
197  auto updateTerminal() const -> bool;
198  static void reduceTerminalLineUpdates (uInt);
199  virtual void addPreprocessingHandler ( const FVTerm*
200  , FPreprocessingFunction&& );
201  virtual void delPreprocessingHandler (const FVTerm*);
202  auto interpretControlCodes (FTermArea*, const FChar&) const noexcept -> bool;
203  template <typename... Args>
204  auto printf (const FString&, Args&&...) noexcept -> int;
205  auto print (const FString&) noexcept -> int;
206  auto print (FTermArea*, const FString&) noexcept -> int;
207  auto print (const std::vector<FChar>&) noexcept -> int;
208  auto print (FTermArea*, const std::vector<FChar>&) noexcept -> int;
209  auto print (FVTermBuffer&) noexcept -> int;
210  auto print (const FVTermBuffer&) noexcept -> int;
211  auto print (FTermArea*, FVTermBuffer&) const noexcept -> int;
212  auto print (FTermArea*, const FVTermBuffer&) const noexcept -> int;
213  auto print (wchar_t) noexcept -> int;
214  auto print (FTermArea*, wchar_t) noexcept -> int;
215  auto print (const FChar&) noexcept -> int;
216  auto print (FTermArea*, const FChar&) const noexcept -> int;
217  virtual void print (const FPoint&);
218  auto print() & -> FVTerm&;
219  void flush() const;
220 
221  protected:
222  struct FShadowBox
223  {
224  FRect box{};
225  FSize shadow{};
226  };
227 
228  // Accessor
229  virtual auto getPrintArea() -> FTermArea*;
230  auto getChildPrintArea() const -> FTermArea*;
231  auto getCurrentPrintArea() const -> FTermArea*;
232  auto getVirtualDesktop() const -> FTermArea*;
233  auto getVirtualTerminal() const -> FTermArea*;
234 
235  // Mutators
236  void setPrintArea (FTermArea*);
237  void setChildPrintArea (FTermArea*);
238  void setActiveArea (FTermArea*) const;
239 
240  // Inquiries
241  auto isActive (const FTermArea*) const -> bool;
242  auto hasPrintArea() const -> bool;
243  auto hasChildPrintArea() const -> bool;
244  auto isVirtualWindow() const -> bool;
245  auto isCursorHideable() const -> bool;
246 
247  // Methods
248  auto createArea (const FShadowBox&) -> std::unique_ptr<FTermArea>;
249  auto createArea (const FRect&) -> std::unique_ptr<FTermArea>;
250  void resizeArea (const FShadowBox&, FTermArea*) const;
251  void resizeArea (const FRect&, FTermArea*) const;
252  void restoreVTerm (const FRect&) const noexcept;
253  auto updateVTermCursor (const FTermArea*) const noexcept -> bool;
254  void hideVTermCursor() const;
255  void setAreaCursor (const FPoint&, bool, FTermArea*) const noexcept;
256  void getArea (const FPoint&, FTermArea*) const noexcept;
257  void getArea (const FRect&, FTermArea*) const noexcept;
258  void addLayer (FTermArea*) const noexcept;
259  void putArea (const FPoint&, const FTermArea*) const noexcept;
260  void copyArea (FTermArea*, const FPoint&, const FTermArea* const) const noexcept;
261  static auto getLayer (FVTerm&) noexcept -> int;
262  static void determineWindowLayers() noexcept;
263  void scrollAreaForward (FTermArea*);
264  void scrollAreaReverse (FTermArea*);
265  void clearArea (FTermArea*, wchar_t = L' ') noexcept;
266  void forceTerminalUpdate() const;
267  auto processTerminalUpdate() const -> bool;
268  static void startDrawing() noexcept;
269  static void finishDrawing() noexcept;
270  virtual void initTerminal();
271 
272  private:
273  // Constants
274  static constexpr int DEFAULT_MINIMIZED_HEIGHT = 1;
275 
276  // Enumeration
277  enum class CoveredState
278  {
279  None,
280  Half,
281  Full
282  };
283 
284  // Methods
285  static void setGlobalFVTermInstance (FVTerm* ptr);
286  static auto getGlobalFVTermInstance() -> FVTerm*&;
287  static auto isInitialized() -> bool;
288  void resetAreaEncoding() const;
289  void resetTextAreaToDefault (FTermArea*, const FSize&) const noexcept;
290  auto resizeTextArea (FTermArea*, std::size_t, std::size_t ) const -> bool;
291  auto resizeTextArea (FTermArea*, std::size_t) const -> bool;
292  auto isCovered (const FPoint&, const FTermArea*) const noexcept -> CoveredState;
293  auto isAreaValid (const FShadowBox&) const -> bool;
294  auto isSizeEqual (const FTermArea*, const FShadowBox&) const -> bool;
295  constexpr auto needsHeightResize (const FTermArea*, const std::size_t) const noexcept -> bool;
296  constexpr auto needsWidthResize (const FTermArea*, const std::size_t) const noexcept -> bool;
297  auto tryResizeArea (FTermArea*, const std::size_t, const std::size_t) const -> bool;
298  void updateAreaProperties (FTermArea*, const FShadowBox&) const;
299  constexpr auto getFullAreaWidth (const FTermArea*) const noexcept -> int;
300  constexpr auto getFullAreaHeight (const FTermArea*) const noexcept -> int;
301  void passChangesToOverlap (const FTermArea*) const;
302  void passChangesToOverlappingWindow (FTermArea*, const FTermArea*) const;
303  void passChangesToOverlappingWindowLine (FTermArea*, int, const FTermArea*) const;
304  int calculateStartCoordinate (int, int) const noexcept;
305  int calculateEndCoordinate (int, int, int, int) const noexcept;
306  void restoreOverlaidWindows (const FTermArea* area) const noexcept;
307  void updateVTerm() const;
308  void scrollTerminalForward() const;
309  void scrollTerminalReverse() const;
310  void callPreprocessingHandler (const FTermArea*) const;
311  auto hasChildAreaChanges (const FTermArea*) const -> bool;
312  void clearChildAreaChanges (const FTermArea*) const;
313  auto isInsideArea (const FPoint&, const FTermArea*) const -> bool;
314  auto isFCharTransparent (const FChar&) const -> bool;
315  auto isTransparentInvisible (const FChar&) const -> bool;
316  static void defineByte1TransparentMask();
317  template <typename FOutputType>
318  void init();
319  void initSettings();
320  void finish() const;
321  void saveCurrentVTerm() const;
322  void putAreaLine (const FChar&, FChar&, const std::size_t) const;
323  void putAreaLineWithTransparency (const FChar*, FChar*, const int, FPoint) const;
324  void putTransparentAreaLine (const FPoint&, const std::size_t) const;
325  void addAreaLineWithTransparency (const FChar*, FChar*, const std::size_t) const;
326  void addTransparentAreaLine (const FChar&, FChar&, const std::size_t) const;
327  void addTransparentAreaChar (const FChar&, FChar&) const;
328  auto clearFullArea (FTermArea*, FChar&) const -> bool;
329  void clearAreaWithShadow (FTermArea*, const FChar&) const noexcept;
330  auto printWrap (FTermArea*) const -> bool;
331  auto getByte1PrintTransMask() const -> uInt8;
332  auto changedToTransparency (const FChar&, const FChar&) const -> bool;
333  auto changedFromTransparency (const FChar&, const FChar&) const -> bool;
334  auto printCharacterOnCoordinate ( FTermArea*
335  , const FChar&) const noexcept -> std::size_t;
336  void printPaddingCharacter (FTermArea*, const FChar&) const;
337  void putNonTransparent (std::size_t&, const FChar*, FChar*&) const;
338  void addTransparent (std::size_t&, const FChar*, FChar*&) const;
339  void putTransparent (std::size_t&, const FPoint&, FChar*&) const;
340  auto isInsideTerminal (const FPoint&) const noexcept -> bool;
341  auto canUpdateTerminalNow() const -> bool;
342  static auto hasPendingUpdates (const FTermArea*) noexcept -> bool;
343 
344  // Data members
345  FTermArea* print_area{nullptr}; // Print area for this object
346  FTermArea* child_print_area{nullptr}; // Print area for children
347  FVTermBuffer vterm_buffer{}; // Print buffer
348  FChar nc{}; // next character
349  std::unique_ptr<FTermArea> vwin{}; // Virtual window
350  std::shared_ptr<FOutput> foutput{}; // Terminal output class
351  std::shared_ptr<FVTermList> window_list{}; // List of all window owner
352  std::shared_ptr<FTermArea> vterm{}; // Virtual terminal
353  std::shared_ptr<FTermArea> vterm_old{}; // Last virtual terminal
354  std::shared_ptr<FTermArea> vdesktop{}; // Virtual desktop
355  static FTermArea* active_area; // Active area
356  static uInt8 b1_print_trans_mask; // Transparency mask
357  static int tabstop;
358  static bool draw_completed;
359  static bool skip_one_vterm_update;
360  static bool no_terminal_updates;
361  static bool force_terminal_update;
362 
363  // Friend function
364  friend void setPrintArea (FWidget&, FTermArea*);
365  friend auto getColumnWidth (const wchar_t wchar) -> std::size_t;
366 };
367 
368 
369 //----------------------------------------------------------------------
370 // struct FVTerm::FTermArea
371 //----------------------------------------------------------------------
372 
373 struct FVTerm::FTermArea // Define virtual terminal character properties
374 {
375  // Using-declaration
376  using FDataAccessPtr = std::shared_ptr<FDataAccess>;
377  using FLineChangesPtr = std::vector<FLineChanges>;
378  using FCharPtr = std::vector<FChar>;
379 
380  // Constructor
381  FTermArea() = default;
382 
383  // Disable copy constructor
384  FTermArea (const FTermArea&) = delete;
385 
386  // Destructor
387  ~FTermArea() = default;
388 
389  // Disable copy assignment operator (=)
390  auto operator = (const FTermArea&) -> FTermArea& = delete;
391 
392  template <typename T>
393  inline auto getOwner() const -> clean_fdata_t<T>&
394  {
395  return static_cast<FData<clean_fdata_t<T>>&>(*owner).get();
396  }
397 
398  template <typename T>
399  inline void setOwner (T&& obj)
400  {
401  owner.reset(makeFData(std::forward<T>(obj)));
402  }
403 
404  inline auto hasOwner() const -> bool
405  {
406  return owner.get() != nullptr;
407  }
408 
409  auto contains (const FPoint&) const noexcept -> bool;
410  auto isOverlapped (const FRect&) const noexcept -> bool;
411  auto isOverlapped (const FTermArea*) const noexcept -> bool;
412  auto checkPrintPos() const noexcept -> bool;
413  auto reprint (const FRect&, const FSize&) noexcept -> bool;
414 
415  inline auto getFChar (int x, int y) const noexcept -> const FChar&
416  {
417  return data[unsigned(y) * unsigned(size.width + shadow.width) + unsigned(x)];
418  }
419 
420  inline auto getFChar (int x, int y) noexcept -> FChar&
421  {
422  return data[unsigned(y) * unsigned(size.width + shadow.width) + unsigned(x)];
423  }
424 
425  inline auto getFChar (const FPoint& pos) const noexcept -> const FChar&
426  {
427  return getFChar(pos.getX(), pos.getY());
428  }
429 
430  inline auto getFChar (const FPoint& pos) noexcept -> FChar&
431  {
432  return getFChar(pos.getX(), pos.getY());
433  }
434 
435  inline void setCursorPos (int x, int y) noexcept
436  {
437  cursor.x = x;
438  cursor.y = y;
439  }
440 
441  inline void setInputCursorPos (int x, int y) noexcept
442  {
443  input_cursor.x = x;
444  input_cursor.y = y;
445  }
446 
447  template <typename T>
448  inline auto print (T&& term_data) -> int
449  {
450  if ( hasOwner() )
451  return getOwner<FVTerm*>()->print (this, std::forward<T>(term_data));
452 
453  return -1;
454  }
455 
456  // Data members
457  struct Coordinate
458  {
459  int x{};
460  int y{};
461  };
462 
463  struct Dimension
464  {
465  int width{};
466  int height{};
467  };
468 
469  Coordinate position{0, 0}; // Distance from left and top of terminal edge
470  Dimension size{-1, -1}; // Window width and height
471  Dimension shadow{0, 0}; // Right and bottom window shadow
472  Dimension min_size{-1, -1}; // Minimized window width and height
473  Coordinate cursor{0, 0}; // Position for the next write operation
474  Coordinate input_cursor{-1, -1}; // Position of visible input cursor
475  int layer{-1};
476  Encoding encoding{Encoding::Unknown};
477  bool input_cursor_visible{false};
478  bool has_changes{false};
479  bool visible{false};
480  bool minimized{false};
481  FDataAccessPtr owner{nullptr}; // Object that owns this FTermArea
482  FPreprocVector preproc_list{};
483  FLineChangesPtr changes{};
484  FCharPtr data{}; // FChar data of the drawing area
485 };
486 
487 //----------------------------------------------------------------------
488 inline auto FVTerm::FTermArea::contains (const FPoint& pos) const noexcept -> bool
489 {
490  // Is the terminal position (pos) located on my area?
491 
492  const int current_height = minimized ? min_size.height : size.height + shadow.height;
493  const int x = pos.getX();
494  const int y = pos.getY();
495  return x >= position.x
496  && x < position.x + size.width + shadow.width
497  && y >= position.y
498  && y < position.y + current_height;
499 }
500 
501 //----------------------------------------------------------------------
502 inline auto FVTerm::FTermArea::isOverlapped (const FRect& box) const noexcept -> bool
503 {
504  const int current_height = minimized ? min_size.height
505  : size.height + shadow.height;
506  const int x1 = position.x;
507  const int x2 = position.x + size.width + shadow.width - 1;
508  const int y1 = position.y;
509  const int y2 = position.y + current_height - 1;
510 
511  return ( std::max(x1, box.getX1() - 1) <= std::min(x2, box.getX2() - 1)
512  && std::max(y1, box.getY1() - 1) <= std::min(y2, box.getY2() - 1) );
513 }
514 
515 //----------------------------------------------------------------------
516 inline auto FVTerm::FTermArea::isOverlapped (const FTermArea* area) const noexcept -> bool
517 {
518  const int current_height = minimized ? min_size.height
519  : size.height + shadow.height;
520  const int x1 = position.x;
521  const int x2 = position.x + size.width + shadow.width - 1;
522  const int y1 = position.y;
523  const int y2 = position.y + current_height - 1;
524 
525  const int area_current_height = area->minimized ? area->min_size.height
526  : area->size.height + area->shadow.height;
527  const int area_x1 = area->position.x;
528  const int area_x2 = area->position.x + area->size.width + area->shadow.width - 1;
529  const int area_y1 = area->position.y;
530  const int area_y2 = area->position.y + area_current_height - 1;
531 
532  return ( std::max(x1, area_x1) <= std::min(x2, area_x2)
533  && std::max(y1, area_y1) <= std::min(y2, area_y2) );
534 }
535 
536 //----------------------------------------------------------------------
537 inline auto FVTerm::FTermArea::checkPrintPos() const noexcept -> bool
538 {
539  return cursor.x > 0
540  && cursor.y > 0
541  && cursor.x <= size.width + shadow.width
542  && cursor.y <= size.height + shadow.height;
543 }
544 
545 
546 //----------------------------------------------------------------------
547 inline auto FVTerm::FTermArea::reprint (const FRect& box, const FSize& term_size) noexcept -> bool
548 {
549  if ( ! isOverlapped(box) )
550  return false;
551 
552  const int x_pos = box.getX() - 1;
553  const int y_pos = box.getY() - 1;
554  const auto w = int(box.getWidth());
555  const auto h = int(box.getHeight());
556 
557  if ( w == 0 || h == 0 )
558  return false;
559 
560  has_changes = true;
561  const int y_start = std::max(0, std::max(y_pos, position.y)) - position.y;
562  const int box_y2 = y_pos + h - 1;
563  const int current_height = minimized ? min_size.height : size.height + shadow.height;
564  const int y2 = position.y + current_height - 1;
565  const int y_end = std::min(int(term_size.getHeight()) - 1, std::min(box_y2, y2)) - position.y;
566 
567  for (auto y{y_start}; y <= y_end; y++) // Line loop
568  {
569  const int x_start = std::max(0, std::max(x_pos, position.x)) - position.x;
570  const int box_x2 = x_pos + w - 1;
571  const int x2 = position.x + size.width + shadow.width - 1;
572  const int x_end = std::min(int(term_size.getWidth()) - 1 , std::min(box_x2, x2)) - position.x;
573  auto& line_changes = changes[std::size_t(y)];
574  line_changes.xmin = uInt(std::min(int(line_changes.xmin), x_start));
575  line_changes.xmax = uInt(std::max(int(line_changes.xmax), x_end));
576  }
577 
578  return true;
579 }
580 
581 
582 //----------------------------------------------------------------------
583 // struct FVTerm::FVTermPreprocessing
584 //----------------------------------------------------------------------
585 struct D
586 {
587  void operator () (const FVTerm*) const noexcept
588  {
589  // No deleting of pointer objects when exiting the std::unique_ptr
590  }
591 };
592 
594 {
595  // Constructor
596  FVTermPreprocessing (const FVTerm* i, FPreprocessingFunction&& f)
597  : instance(std::unique_ptr<const FVTerm, D>(i))
598  , function(std::move(f))
599  { }
600 
601  FVTermPreprocessing (const FVTermPreprocessing&) = delete;
602  FVTermPreprocessing (FVTermPreprocessing&&) noexcept = default;
603  auto operator = (const FVTermPreprocessing&) -> FVTermPreprocessing& = delete;
604  auto operator = (FVTermPreprocessing&&) noexcept -> FVTermPreprocessing& = default;
605 
606  // Data members
607  std::unique_ptr<const FVTerm, D> instance{};
608  FPreprocessingFunction function{};
609 };
610 
611 
612 // FVTerm inline functions
613 //----------------------------------------------------------------------
614 template <typename FOutputType>
615 FVTerm::FVTerm (outputClass<FOutputType>)
616 {
617  init<typename outputClass<FOutputType>::type>();
618 }
619 
620 //----------------------------------------------------------------------
621 template <typename NumT
622  , enable_if_arithmetic_without_char_t<NumT>>
623 inline auto FVTerm::operator << (const NumT& n) noexcept -> FVTerm&
624 {
625  print (FString(std::to_string(n)));
626  return *this;
627 }
628 
629 //----------------------------------------------------------------------
630 template <typename CharT
631  , enable_if_CString_t<CharT>>
632 inline auto FVTerm::operator << (const CharT& s) noexcept -> FVTerm&
633 {
634  print (FString(s));
635  return *this;
636 }
637 
638 //----------------------------------------------------------------------
639 inline auto FVTerm::operator << (char c) noexcept -> FVTerm&
640 {
641  print (wchar_t(uChar(c)));
642  return *this;
643 }
644 
645 //----------------------------------------------------------------------
646 inline auto FVTerm::operator << (wchar_t c) noexcept -> FVTerm&
647 {
648  print (c);
649  return *this;
650 }
651 
652 //----------------------------------------------------------------------
653 inline auto FVTerm::operator << (const wchar_t* wide_string) noexcept -> FVTerm&
654 {
655  print (FString(wide_string));
656  return *this;
657 }
658 
659 //----------------------------------------------------------------------
660 inline auto FVTerm::operator << (const UniChar& c) noexcept -> FVTerm&
661 {
662  print (static_cast<wchar_t>(c)); // Required under Solaris
663  return *this;
664 }
665 
666 //----------------------------------------------------------------------
667 inline auto FVTerm::operator << (const std::string& string) noexcept -> FVTerm&
668 {
669  print (FString(string));
670  return *this;
671 }
672 
673 //----------------------------------------------------------------------
674 inline auto FVTerm::operator << (const std::wstring& wide_string) noexcept -> FVTerm&
675 {
676  print (FString(wide_string));
677  return *this;
678 }
679 
680 //----------------------------------------------------------------------
681 inline auto FVTerm::operator << (const FString& fstring) noexcept -> FVTerm&
682 {
683  print (fstring);
684  return *this;
685 }
686 
687 //----------------------------------------------------------------------
688 inline auto FVTerm::operator << (const FChar& fchar) noexcept -> FVTerm&
689 {
690  print (fchar);
691  return *this;
692 }
693 
694 //----------------------------------------------------------------------
695 inline auto FVTerm::operator << (const FCharVector& term_string) noexcept -> FVTerm&
696 {
697  print (term_string);
698  return *this;
699 }
700 
701 //----------------------------------------------------------------------
702 inline auto FVTerm::operator << (const FPoint& pos) noexcept -> FVTerm&
703 {
704  print (pos);
705  return *this;
706 }
707 
708 //----------------------------------------------------------------------
709 inline auto FVTerm::operator << (const FStyle& t_style) noexcept -> FVTerm&
710 {
711  print (t_style);
712  return *this;
713 }
714 
715 //----------------------------------------------------------------------
716 inline auto FVTerm::operator << (const FColorPair& pair) noexcept -> FVTerm&
717 {
718  print (pair);
719  return *this;
720 }
721 
722 //----------------------------------------------------------------------
723 inline auto FVTerm::getClassName() const -> FString
724 { return "FVTerm"; }
725 
726 //----------------------------------------------------------------------
727 inline auto FVTerm::getVWin() noexcept -> FTermArea*
728 { return vwin.get(); }
729 
730 //----------------------------------------------------------------------
731 inline auto FVTerm::getVWin() const noexcept -> const FTermArea*
732 { return vwin.get(); }
733 
734 //----------------------------------------------------------------------
735 inline auto FVTerm::getWindowList() -> FVTermList*
736 {
737  static const auto& init_object = getGlobalFVTermInstance();
738  return (isInitialized() && init_object->window_list)
739  ? init_object->window_list.get()
740  : nullptr;
741 }
742 
743 //----------------------------------------------------------------------
744 inline void FVTerm::setVWin (std::unique_ptr<FTermArea>&& area) noexcept
745 { vwin = std::move(area); }
746 
747 //----------------------------------------------------------------------
748 inline void FVTerm::unsetNonBlockingRead()
749 { setNonBlockingRead(false); }
750 
751 //----------------------------------------------------------------------
752 inline auto FVTerm::isDrawingFinished() noexcept -> bool
753 { return draw_completed; }
754 
755 //----------------------------------------------------------------------
756 inline auto FVTerm::isTerminalUpdateForced() noexcept -> bool
757 { return force_terminal_update; }
758 
759 //----------------------------------------------------------------------
760 inline auto FVTerm::areTerminalUpdatesPaused() noexcept -> bool
761 { return no_terminal_updates; }
762 
763 //----------------------------------------------------------------------
764 inline auto FVTerm::hasPendingTerminalUpdates() noexcept -> bool
765 { return hasPendingUpdates(getGlobalFVTermInstance()->vterm.get()); }
766 
767 //----------------------------------------------------------------------
768 template <typename... Args>
769 auto FVTerm::printf (const FString& format, Args&&... args) noexcept -> int
770 {
771  FString str{};
772  str.sprintf (format, std::forward<Args>(args)...);
773  return print(str);
774 }
775 
776 //----------------------------------------------------------------------
777 inline auto FVTerm::print() & -> FVTerm&
778 { return *this; }
779 
780 //----------------------------------------------------------------------
781 inline void FVTerm::print (const FPoint& p)
782 {
783  setCursor (p);
784 }
785 
786 //----------------------------------------------------------------------
787 inline auto FVTerm::getChildPrintArea() const -> FTermArea*
788 { return child_print_area; }
789 
790 //----------------------------------------------------------------------
791 inline auto FVTerm::getCurrentPrintArea() const -> FTermArea*
792 { return print_area; }
793 
794 //----------------------------------------------------------------------
795 inline auto FVTerm::getVirtualDesktop() const -> FTermArea*
796 { return vdesktop.get(); }
797 
798 //----------------------------------------------------------------------
799 inline auto FVTerm::getVirtualTerminal() const -> FTermArea*
800 { return vterm.get(); }
801 
802 //----------------------------------------------------------------------
803 inline void FVTerm::setPrintArea (FTermArea* area)
804 { print_area = area; }
805 
806 //----------------------------------------------------------------------
807 inline void FVTerm::setChildPrintArea (FTermArea* area)
808 { child_print_area = area; }
809 
810 //----------------------------------------------------------------------
811 inline void FVTerm::setActiveArea (FTermArea* area) const
812 { active_area = area; }
813 
814 //----------------------------------------------------------------------
815 inline auto FVTerm::isActive (const FTermArea* area) const -> bool
816 { return area == active_area; }
817 
818 //----------------------------------------------------------------------
819 inline auto FVTerm::hasPrintArea() const -> bool
820 { return print_area; }
821 
822 //----------------------------------------------------------------------
823 inline auto FVTerm::hasChildPrintArea() const -> bool
824 { return child_print_area; }
825 
826 //----------------------------------------------------------------------
827 inline auto FVTerm::isVirtualWindow() const -> bool
828 { return vwin.get(); }
829 
830 //----------------------------------------------------------------------
831 inline void FVTerm::hideVTermCursor() const
832 { vterm->input_cursor_visible = false; }
833 
834 //----------------------------------------------------------------------
835 inline auto FVTerm::getLayer (FVTerm& obj) noexcept -> int
836 {
837  // returns the layer from the FVTerm object
838  return obj.FVTerm::getPrintArea()->layer;
839 }
840 
841 //----------------------------------------------------------------------
842 template <typename FOutputType>
843 inline void FVTerm::init()
844 {
845  if ( ! isInitialized() )
846  {
847  setGlobalFVTermInstance(this);
848  defineByte1TransparentMask();
849  b1_print_trans_mask = getByte1PrintTransMask();
850  foutput = std::make_shared<FOutputType>(*this);
851  window_list = std::make_shared<FVTermList>();
852  initSettings();
853  }
854  else
855  {
856  static const auto& init_object = getGlobalFVTermInstance();
857  foutput = std::shared_ptr<FOutput>(init_object->foutput);
858  window_list = std::shared_ptr<FVTermList>(init_object->window_list);
859  vterm = std::shared_ptr<FTermArea>(init_object->vterm);
860  vterm_old = std::shared_ptr<FTermArea>(init_object->vterm_old);
861  vdesktop = std::shared_ptr<FTermArea>(init_object->vdesktop);
862  }
863 }
864 
865 } // namespace finalcut
866 
867 #endif // FVTERM_H
Definition: frect.h:56
Definition: fvterm.h:96
Definition: fvtermbuffer.h:56
Definition: class_template.cpp:25
Definition: fpoint.h:50
Definition: fsize.h:55
Definition: ftypes.h:423
Definition: fvterm.h:222
Definition: fstring.h:79
Definition: fstyle.h:49
Definition: fvterm.h:102
Definition: fvterm.h:585
Definition: fdata.h:51
Definition: fwidget.h:129
Definition: fcolorpair.h:49
Definition: fvterm.h:87
Definition: fvtermattribute.h:53
Definition: fvterm.h:373