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
 
std::string clear () 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 26 of file terminal_impl.hpp.

Constructor & Destructor Documentation

◆ ~Terminal()

Term::Terminal::~Terminal ( )
noexcept

Definition at line 40 of file terminal_impl.cpp.

42{
43 clean();
44}
45catch(...)
46{
48}
void ExceptionHandler(const ExceptionDestination &destination=ExceptionDestination::StdErr) noexcept

◆ Terminal() [1/3]

Term::Terminal::Terminal ( )
noexcept

Definition at line 28 of file terminal_impl.cpp.

30{
32 setMode(); //Save the default cpp-terminal mode done in store_and_restore();
34}
35catch(...)
36{
38}
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 64 of file terminal_impl.cpp.

65{
68 setMode();
69}
std::size_t write(const std::string &str) const
Definition file.cpp:130
std::string clear() const noexcept
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).
Definition options.hpp:26
@ NoCursor
Hide the cursor (and restore its states when the program stops).
Definition options.hpp:31
std::string cursor_off()
Definition cursor.cpp:24
@ Reset
resets all attributes (styles and colors)
Definition style.hpp:26
std::string cursor_move(const std::size_t &row, const std::size_t &column)
Definition cursor.cpp:28

◆ clean()

void Term::Terminal::clean ( )
private

Definition at line 54 of file terminal_impl.cpp.

55{
62}
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:26

◆ clear()

std::string Term::Terminal::clear ( ) const
noexcept

Definition at line 19 of file terminal_impl.cpp.

19{ return "\u001b[3J"; }

◆ getOptions()

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

Definition at line 21 of file terminal_impl.cpp.

21{ 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 36 of file terminal_impl.cpp.

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

◆ setFocusEvents()

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

Definition at line 149 of file terminal_impl.cpp.

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

◆ 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 167 of file terminal_impl.cpp.

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

◆ setMouseEvents()

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

Definition at line 131 of file terminal_impl.cpp.

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

◆ 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 36 of file terminal_impl.hpp.

37 {
38 m_options = {args...};
40 }
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 77 of file terminal_impl.cpp.

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

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

◆ unsetMouseEvents()

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

Definition at line 140 of file terminal_impl.cpp.

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

Friends And Related Symbol Documentation

◆ Private::Signals

friend class Private::Signals
friend

Definition at line 29 of file terminal_impl.hpp.

Member Data Documentation

◆ m_options

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

Definition at line 66 of file terminal_impl.hpp.


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