cpp-terminal 1.0.0
Small C++ library for writing multiplatform terminal applications
Loading...
Searching...
No Matches
cursor.cpp
Go to the documentation of this file.
1/*
2* cpp-terminal
3* C++ library for writing multi-platform terminal applications.
4*
5* SPDX-FileCopyrightText: 2019-2024 cpp-terminal
6*
7* SPDX-License-Identifier: MIT
8*/
9
11
12#include "file_initializer.hpp"
13
14#if defined(_WIN32)
15 #pragma warning(push)
16 #pragma warning(disable : 4668)
17 #include <windows.h>
18 #pragma warning(pop)
19#else
20 #include <sys/ioctl.h>
21 #include <termios.h>
22#endif
23
25
27{
28 static const Term::Private::FileInitializer files_init;
29 if(Term::Private::in.null()) { return {}; }
30#if defined(_WIN32)
31 CONSOLE_SCREEN_BUFFER_INFO inf;
32 if(GetConsoleScreenBufferInfo(Private::out.handle(), &inf)) return Term::Cursor(static_cast<std::size_t>(inf.dwCursorPosition.Y + 1), static_cast<std::size_t>(inf.dwCursorPosition.X + 1));
33 else
34 return Term::Cursor(0, 0);
35#else
36 std::string ret;
37 std::size_t nread{0};
39 // Hack to be sure we can do this all the time "Cooked" or "Raw" mode
40 ::termios actual;
41 if(!Private::out.null())
42 {
43 if(tcgetattr(Private::out.fd(), &actual) == -1) { return {}; }
44 }
45 ::termios raw = actual;
46 // Put terminal in raw mode
47 raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
48 // This disables output post-processing, requiring explicit \r\n. We
49 // keep it enabled, so that in C++, one can still just use std::endl
50 // for EOL instead of "\r\n".
51 // raw.c_oflag &= ~(OPOST);
52 raw.c_lflag &= ~(ECHO | ICANON | IEXTEN);
53 raw.c_lflag &= ~ISIG;
54 raw.c_cc[VMIN] = 1;
55 raw.c_cc[VTIME] = 0;
56 if(!Private::out.null()) tcsetattr(Private::out.fd(), TCSAFLUSH, &raw);
58 while(nread == 0) { ::ioctl(Private::in.fd(), FIONREAD, &nread); }
59 ret = Term::Private::in.read();
60 tcsetattr(Private::out.fd(), TCSAFLUSH, &actual);
62 try
63 {
64 if(ret[0] == '\033' && ret[1] == '[' && ret[ret.size() - 1] == 'R')
65 {
66 std::size_t found = ret.find(';', 2);
67 if(found != std::string::npos) { return Cursor(std::stoi(ret.substr(2, found - 2)), std::stoi(ret.substr(found + 1, ret.size() - (found + 2)))); }
68 return {};
69 }
70 return {};
71 }
72 catch(...)
73 {
74 return {};
75 }
76#endif
77}
std::string read() const
Definition file.cpp:127
std::size_t write(const std::string &str) const
Definition file.cpp:101
InputFileHandler & in
Definition file.cpp:43
OutputFileHandler & out
Definition file.cpp:44
std::string cursor_position_report()
Definition cursor.cpp:42
@ Cursor
Show the cursor.
Term::Cursor cursor_position()
Definition cursor.cpp:26