libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
terminal.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
13#include <functional>
14#include <promeki/function.h>
15#include <promeki/namespace.h>
16#include <promeki/size2d.h>
17#include <promeki/platform.h>
18#include <promeki/error.h>
19#include <promeki/result.h>
20#include <promeki/uniqueptr.h>
21
22PROMEKI_NAMESPACE_BEGIN
23
24// Terminal owns an internal AnsiStream layered over a File that adopts the
25// output fd (with BufferedIODevice write buffering enabled) and routes ALL
26// escape-sequence emission through it, so there is a single ordered, buffered
27// write path to the terminal. Both are held by UniquePtr behind forward
28// declarations: the AnsiStream one breaks a terminal.h <-> ansistream.h
29// include cycle (ansistream.h depends on Terminal::ColorSupport), and
30// forward-declaring File keeps file.h out of this header.
31class AnsiStream;
32class File;
33
51class Terminal {
52 public:
53
75 enum ColorSupport {
76 NoColor,
77 Grayscale16,
78 Grayscale256,
79 GrayscaleTrue,
80 Basic,
81 Color256,
82 TrueColor
83 };
84
86 Terminal();
87
93 Terminal(int inputFd, int outputFd);
94
96 ~Terminal();
97
98 Terminal(const Terminal &) = delete;
99 Terminal &operator=(const Terminal &) = delete;
100
102 int inputFd() const { return _inputFd; }
103
105 int outputFd() const { return _outputFd; }
106
111 Error enableRawMode();
112
117 Error disableRawMode();
118
120 bool isRawMode() const { return _rawMode; }
121
129 Result<int> readInput(char *buf, int maxLen);
130
137 Error windowSize(int &cols, int &rows) const;
138
142 Size2Di32 size() const;
143
148 Error enableMouseTracking();
149
154 Error disableMouseTracking();
155
157 bool isMouseTrackingEnabled() const { return _mouseTracking; }
158
163 Error enableBracketedPaste();
164
169 Error disableBracketedPaste();
170
179 Error enableFocusReporting();
180
185 Error disableFocusReporting();
186
188 bool isFocusReportingEnabled() const { return _focusReporting; }
189
194 Error enableAlternateScreen();
195
200 Error disableAlternateScreen();
201
218 static ColorSupport colorSupport();
219
227 Result<int> writeOutput(const char *data, int len);
228
241 AnsiStream &ansiStream();
242
258 void emergencyRestore();
259
266 class RawModeGuard {
267 public:
269 explicit RawModeGuard(Terminal &t) : _t(t) { _t.enableRawMode(); }
271 ~RawModeGuard() { _t.disableRawMode(); }
272 RawModeGuard(const RawModeGuard &) = delete;
273 RawModeGuard &operator=(const RawModeGuard &) = delete;
274
275 private:
276 Terminal &_t;
277 };
278
280 class AlternateScreenGuard {
281 public:
283 explicit AlternateScreenGuard(Terminal &t) : _t(t) { _t.enableAlternateScreen(); }
285 ~AlternateScreenGuard() { _t.disableAlternateScreen(); }
286 AlternateScreenGuard(const AlternateScreenGuard &) = delete;
287 AlternateScreenGuard &operator=(const AlternateScreenGuard &) = delete;
288
289 private:
290 Terminal &_t;
291 };
292
294 class MouseTrackingGuard {
295 public:
297 explicit MouseTrackingGuard(Terminal &t) : _t(t) { _t.enableMouseTracking(); }
299 ~MouseTrackingGuard() { _t.disableMouseTracking(); }
300 MouseTrackingGuard(const MouseTrackingGuard &) = delete;
301 MouseTrackingGuard &operator=(const MouseTrackingGuard &) = delete;
302
303 private:
304 Terminal &_t;
305 };
306
308 class BracketedPasteGuard {
309 public:
311 explicit BracketedPasteGuard(Terminal &t) : _t(t) { _t.enableBracketedPaste(); }
313 ~BracketedPasteGuard() { _t.disableBracketedPaste(); }
314 BracketedPasteGuard(const BracketedPasteGuard &) = delete;
315 BracketedPasteGuard &operator=(const BracketedPasteGuard &) = delete;
316
317 private:
318 Terminal &_t;
319 };
320
322 class FocusReportingGuard {
323 public:
325 explicit FocusReportingGuard(Terminal &t) : _t(t) { _t.enableFocusReporting(); }
327 ~FocusReportingGuard() { _t.disableFocusReporting(); }
328 FocusReportingGuard(const FocusReportingGuard &) = delete;
329 FocusReportingGuard &operator=(const FocusReportingGuard &) = delete;
330
331 private:
332 Terminal &_t;
333 };
334
335 private:
336 void init();
337
338 int _inputFd;
339 int _outputFd;
340 bool _rawMode = false;
341 bool _mouseTracking = false;
342 bool _bracketedPaste = false;
343 bool _alternateScreen = false;
344 bool _focusReporting = false;
345
346 // Single ordered write path: a File adopting the output fd and
347 // the AnsiStream layered over it. Created in init(). Held by
348 // UniquePtr behind forward declarations to keep this header
349 // free of the file.h / ansistream.h includes (see top of file).
350 UniquePtr<File> _outDevice;
351 UniquePtr<AnsiStream> _ansi;
352
353 // Opaque storage for platform-specific terminal state.
354 // On POSIX this holds a struct termios.
355 void *_origState = nullptr;
356};
357
358PROMEKI_NAMESPACE_END
359
360#endif // PROMEKI_ENABLE_CORE