cpp-terminal 1.0.0
Small C++ library for writing multiplatform terminal applications
Loading...
Searching...
No Matches
Term::Terminal Class Reference

#include <cpp-terminal/terminal_impl.hpp>

Public Member Functions

 ~Terminal () noexcept
 
 Terminal () noexcept
 
 Terminal (const Terminal &)=delete
 
 Terminal (Terminal &&)=delete
 
Terminaloperator= (Terminal &&)=delete
 
Terminaloperator= (const Terminal &)=delete
 
template<typename... Args>
void setOptions (const Args &&... args)
 
Term::Options getOptions () const noexcept
 

Private Member Functions

void setMode () const
 Set mode raw/cooked.
 
void setOptions ()
 
void applyOptions () const
 
void clean ()
 

Static Private Member Functions

static void store_and_restore () noexcept
 Store and restore the default state of the terminal.
 
static std::size_t setMouseEvents ()
 
static std::size_t unsetMouseEvents ()
 
static std::size_t setFocusEvents ()
 
static std::size_t unsetFocusEvents ()
 
static void set_unset_utf8 ()
 

Private Attributes

Term::Options m_options
 

Friends

class Private::Signals
 

Detailed Description

Definition at line 21 of file terminal_impl.hpp.

Constructor & Destructor Documentation

◆ ~Terminal()

Term::Terminal::~Terminal ( )
noexcept

Definition at line 44 of file terminal_impl.cpp.

46{
47 clean();
48}
49catch(...)
50{
52}
void ExceptionHandler(const ExceptionDestination &destination=ExceptionDestination::StdErr) noexcept

◆ Terminal() [1/3]

Term::Terminal::Terminal ( )
noexcept

Definition at line 22 of file terminal_impl.cpp.

24{
26 setMode(); //Save the default cpp-terminal mode done in store_and_restore();
28}
29catch(...)
30{
32}
void setMode() const
Set mode raw/cooked.
static void set_unset_utf8()
static void store_and_restore() noexcept
Store and restore the default state of the terminal.

◆ Terminal() [2/3]

Term::Terminal::Terminal ( const Terminal & )
delete

◆ Terminal() [3/3]

Term::Terminal::Terminal ( Terminal && )
delete

Member Function Documentation

◆ applyOptions()

void Term::Terminal::applyOptions ( ) const
private

Definition at line 54 of file terminal_impl.cpp.

55{
58 setMode();
59}
std::size_t write(const std::string &str) const
Definition file.cpp:101
Term::Options getOptions() const noexcept
OutputFileHandler & out
Definition file.cpp:44
std::string screen_save()
Definition screen.cpp:22
std::string style(const Term::Style &style)
Definition style.cpp:12
@ ClearScreen
Clear the screen (and restore its states when the program stops).
@ NoCursor
Hide the cursor (and restore its states when the program stops).
std::string cursor_off()
Definition cursor.cpp:28
@ Reset
resets all attributes (styles and colors)
std::string cursor_move(const std::size_t &row, const std::size_t &column)
Definition cursor.cpp:32
std::string clear_buffer()
Definition terminal.cpp:23

◆ clean()

void Term::Terminal::clean ( )
private

Definition at line 34 of file terminal_impl.cpp.

35{
42}
static std::size_t unsetMouseEvents()
static std::size_t unsetFocusEvents()
std::string screen_load()
Definition screen.cpp:27
std::string cursor_on()
Definition cursor.cpp:30

◆ getOptions()

Term::Options Term::Terminal::getOptions ( ) const
noexcept

Definition at line 20 of file terminal_impl.cpp.

20{ return m_options; }
Term::Options m_options

◆ operator=() [1/2]

Terminal & Term::Terminal::operator= ( const Terminal & )
delete

◆ operator=() [2/2]

Terminal & Term::Terminal::operator= ( Terminal && )
delete

◆ set_unset_utf8()

void Term::Terminal::set_unset_utf8 ( )
staticprivate

Definition at line 37 of file terminal_impl.cpp.

38{
39 static bool enabled{false};
40#if defined(_WIN32)
41 static UINT out_code_page{0};
42 static UINT in_code_page{0};
43 if(!enabled)
44 {
45 if((out_code_page = GetConsoleOutputCP()) == 0) throw Term::Private::WindowsException(GetLastError(), "GetConsoleOutputCP()");
46 if(!SetConsoleOutputCP(CP_UTF8)) throw Term::Private::WindowsException(GetLastError(), "SetConsoleOutputCP(CP_UTF8)");
47 if((in_code_page = GetConsoleCP()) == 0) throw Term::Private::WindowsException(GetLastError(), "GetConsoleCP()");
48 if(!SetConsoleCP(CP_UTF8)) throw Term::Private::WindowsException(GetLastError(), "SetConsoleCP(CP_UTF8)");
49 enabled = true;
50 }
51 else
52 {
53 if(!SetConsoleOutputCP(out_code_page)) throw Term::Private::WindowsException(GetLastError(), "SetConsoleOutputCP(out_code_page)");
54 if(!SetConsoleCP(in_code_page)) throw Term::Private::WindowsException(GetLastError(), "SetConsoleCP(in_code_page)");
55 }
56#else
57 if(!enabled)
58 {
59 const Term::Cursor cursor_before{Term::cursor_position()};
60 Term::Private::out.write("\u001b%G"); // Try to activate UTF-8 (NOT warranty)
61 const std::string read{Term::Private::in.read()};
62 const Term::Cursor cursor_after{Term::cursor_position()};
63 const std::size_t moved{cursor_after.column() - cursor_before.column()};
64 std::string rem;
65 rem.reserve(moved * 3);
66 for(std::size_t i = 0; i != moved; ++i) { rem += "\b \b"; }
68 enabled = 0 == moved;
69 }
70 else
71 {
72 // Does not return the original charset but, the default defined by standard ISO 8859-1 (ISO 2022);
73 Term::Private::out.write("\u001b%@");
74 }
75#endif
76}
std::size_t column() const
Definition cursor.cpp:16
std::string read() const
Definition file.cpp:127
InputFileHandler & in
Definition file.cpp:43
Term::Cursor cursor_position()
Definition cursor.cpp:26

◆ setFocusEvents()

std::size_t Term::Terminal::setFocusEvents ( )
staticprivate

Definition at line 150 of file terminal_impl.cpp.

151{
152#if defined(_WIN32)
153 return static_cast<std::size_t>(ENABLE_WINDOW_INPUT);
154#else
155 return Term::Private::out.write("\u001b[?1004h");
156#endif
157}

◆ setMode()

void Term::Terminal::setMode ( ) const
private

Set mode raw/cooked.

First call is to save the good state set-up by cpp-terminal.

Definition at line 168 of file terminal_impl.cpp.

169{
170 static bool activated{false};
171#if defined(_WIN32)
172 static DWORD flags{0};
173 if(!activated)
174 {
175 if(!Private::out.null())
176 if(!GetConsoleMode(Private::in.handle(), &flags)) { throw Term::Private::WindowsException(GetLastError()); }
177 activated = true;
178 return;
179 }
180 DWORD send = flags;
182 {
183 send &= ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT);
184 send |= (setFocusEvents() | setMouseEvents());
185 }
187 {
188 send |= (ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT);
189 send &= ~(setFocusEvents() | setMouseEvents());
190 }
191 if(m_options.has(Option::NoSignalKeys)) { send &= ~ENABLE_PROCESSED_INPUT; }
192 else if(m_options.has(Option::SignalKeys)) { send |= ENABLE_PROCESSED_INPUT; }
193 if(!Private::out.null())
194 if(!SetConsoleMode(Private::in.handle(), send)) { throw Term::Private::WindowsException(GetLastError()); }
195#else
196 if(!Private::out.null())
197 {
198 static ::termios raw = {};
199 if(!activated)
200 {
201 Term::Private::Errno().check_if(tcgetattr(Private::out.fd(), &raw) == -1).throw_exception("tcgetattr(Private::out.fd(), &raw)");
202 raw.c_cflag &= ~static_cast<std::size_t>(CSIZE | PARENB);
203 raw.c_cflag |= CS8;
204 raw.c_cc[VMIN] = 1;
205 raw.c_cc[VTIME] = 0;
206 activated = true;
207 return;
208 }
209 ::termios send = raw;
211 {
212 send.c_iflag &= ~static_cast<std::size_t>(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON | INPCK);
213 // This disables output post-processing, requiring explicit \r\n. We
214 // keep it enabled, so that in C++, one can still just use std::endl
215 // for EOL instead of "\r\n".
216 //send.c_oflag &= ~static_cast<std::size_t>(OPOST);
217 send.c_lflag &= ~static_cast<std::size_t>(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
220 }
222 {
223 send = raw;
226 }
227 if(m_options.has(Option::NoSignalKeys)) { send.c_lflag &= ~static_cast<std::size_t>(ISIG); } //FIXME need others flags !
228 if(m_options.has(Option::SignalKeys)) { send.c_lflag |= ISIG; }
229 Term::Private::Errno().check_if(tcsetattr(Private::out.fd(), TCSAFLUSH, &send) == -1).throw_exception("tcsetattr(Private::out.fd(), TCSAFLUSH, &send)");
230 }
231#endif
232}
bool has(const Option &option) const noexcept
Definition options.cpp:35
void throw_exception(const std::string &str={}) const
Errno & check_if(const bool &ret) noexcept
static std::size_t setFocusEvents()
static std::size_t setMouseEvents()
@ Cooked
Set terminal in cooked mode.
@ Raw
Set terminal in raw mode.
@ NoSignalKeys
Disable the signal keys (Ctrl+C, etc...) will not be processed by the OS and will appears has standar...
@ SignalKeys
Enable the signal keys (Ctrl+C, etc...), if activated these keys will have their default OS behaviour...

◆ setMouseEvents()

std::size_t Term::Terminal::setMouseEvents ( )
staticprivate

Definition at line 132 of file terminal_impl.cpp.

133{
134#if defined(_WIN32)
135 return static_cast<std::size_t>(ENABLE_MOUSE_INPUT);
136#else
137 return Term::Private::out.write("\u001b[?1002h\u001b[?1003h\u001b[?1006h");
138#endif
139}

◆ setOptions() [1/2]

void Term::Terminal::setOptions ( )
private

◆ setOptions() [2/2]

template<typename... Args>
void Term::Terminal::setOptions ( const Args &&... args)
inline

Definition at line 31 of file terminal_impl.hpp.

32 {
33 m_options = {args...};
35 }
void applyOptions() const

◆ store_and_restore()

void Term::Terminal::store_and_restore ( )
staticprivatenoexcept

Store and restore the default state of the terminal.

Configure the default mode for cpp-terminal.

Definition at line 78 of file terminal_impl.cpp.

80{
81 static bool enabled{false};
82#if defined(_WIN32)
83 static DWORD originalOut{0};
84 static DWORD originalIn{0};
85 if(!enabled)
86 {
87 Term::Private::WindowsError().check_if(GetConsoleMode(Private::out.handle(), &originalOut) == 0).throw_exception("GetConsoleMode(Private::out.handle(), &originalOut)");
88 Term::Private::WindowsError().check_if(GetConsoleMode(Private::in.handle(), &originalIn) == 0).throw_exception("GetConsoleMode(Private::in.handle(), &originalIn)");
89 DWORD in{static_cast<DWORD>((originalIn & ~(ENABLE_QUICK_EDIT_MODE | setFocusEvents() | setMouseEvents())) | (ENABLE_EXTENDED_FLAGS))};
90 DWORD out{originalOut};
91 // Check if ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN can be activated, if not we are a legacy terminal.
92 DWORD test = out;
94 if(!SetConsoleMode(Private::out.handle(), test)) { SetConsoleMode(Private::out.handle(), out); }
95 else
96 {
99 }
100 if(!SetConsoleMode(Private::out.handle(), out)) { throw Term::Private::WindowsException(GetLastError(), "SetConsoleMode(Private::out.handle()"); }
101 if(!SetConsoleMode(Private::in.handle(), in)) { throw Term::Private::WindowsException(GetLastError(), "SetConsoleMode(Private::in.handle(), in)"); }
102 enabled = true;
103 }
104 else
105 {
106 if(!SetConsoleMode(Private::out.handle(), originalOut)) { throw Term::Private::WindowsException(GetLastError(), "SetConsoleMode(Private::out.handle(), originalOut)"); }
107 if(!SetConsoleMode(Private::in.handle(), originalIn)) { throw Term::Private::WindowsException(GetLastError(), "SetConsoleMode(Private::in.handle(), originalIn)"); }
108 }
109#else
110 static termios orig_termios;
111 if(!enabled)
112 {
115 if(!Private::out.null()) { Term::Private::Errno().check_if(tcgetattr(Private::out.fd(), &orig_termios) == -1).throw_exception("tcgetattr() failed"); }
116 enabled = true;
117 }
118 else
119 {
123 if(!Private::out.null()) { Term::Private::Errno().check_if(tcsetattr(Private::out.fd(), TCSAFLUSH, &orig_termios) == -1).throw_exception("tcsetattr() failed in destructor"); }
124 }
125#endif
126}
127catch(...)
128{
130}
static void registerSigwinch()
Definition sigwinch.cpp:49
static void unblockSigwinch()
Definition sigwinch.cpp:75
static void blockSigwinch()
Definition sigwinch.cpp:65
WindowsError & check_if(const bool &ret) noexcept
Definition exception.cpp:75
void throw_exception(const std::string &str=std::string()) const
Definition exception.cpp:82
#define DISABLE_NEWLINE_AUTO_RETURN
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_INPUT

◆ unsetFocusEvents()

std::size_t Term::Terminal::unsetFocusEvents ( )
staticprivate

Definition at line 159 of file terminal_impl.cpp.

160{
161#if defined(_WIN32)
162 return static_cast<std::size_t>(ENABLE_WINDOW_INPUT);
163#else
164 return Term::Private::out.write("\u001b[?1004l");
165#endif
166}

◆ unsetMouseEvents()

std::size_t Term::Terminal::unsetMouseEvents ( )
staticprivate

Definition at line 141 of file terminal_impl.cpp.

142{
143#if defined(_WIN32)
144 return static_cast<std::size_t>(ENABLE_MOUSE_INPUT);
145#else
146 return Term::Private::out.write("\u001b[?1006l\u001b[?1003l\u001b[?1002l");
147#endif
148}

Friends And Related Symbol Documentation

◆ Private::Signals

friend class Private::Signals
friend

Definition at line 24 of file terminal_impl.hpp.

Member Data Documentation

◆ m_options

Term::Options Term::Terminal::m_options
private

Definition at line 59 of file terminal_impl.hpp.


The documentation for this class was generated from the following files: