pubnix/lib/neovision/include/neovision/term.h

155 lines
3.7 KiB
C
Raw Normal View History

2021-08-15 21:31:29 +00:00
#pragma once
2021-08-18 00:36:56 +00:00
#include <signal.h>
2021-08-15 21:31:29 +00:00
#include <termios.h>
2021-08-26 01:28:18 +00:00
#include <chrono>
#include <streambuf>
2021-08-15 21:31:29 +00:00
#include <unordered_map>
namespace neovision {
2021-08-18 00:36:56 +00:00
class Application;
class Vector2D;
/**
* @brief Terminal event callback.
*
* This function signature is used for registering terminal event callbacks.
* The application is passed as a convenience, as anything that needs to be
* accessible within the function can be wired into the application class.
*/
2021-08-26 01:28:18 +00:00
typedef std::function<void()> TerminalEventCallback;
2021-08-18 00:36:56 +00:00
2021-08-15 21:31:29 +00:00
/**
* Class for terminal i/o operations.
*
* Any terminal setting changes made during the lifetime of the class will be
* restored to their previous state when the instance is destroyed.
*
2021-08-18 00:36:56 +00:00
* While you can use this class on it's own, it is sort-of assumed that the
* Terminal is instantiated by the Application class.
* Specifically, the callback functions rely on the 'TheApp' pointer being
* set in order to dispatch their events.
*
2021-08-15 21:31:29 +00:00
* @todo this is going to require platform-specific split implementations.
*/
class Terminal {
2021-08-26 01:28:18 +00:00
bool m_initialized{false};
termios m_savedTerminalSettings{};
2021-08-18 00:36:56 +00:00
TerminalEventCallback m_onResize;
2021-08-26 01:28:18 +00:00
TerminalEventCallback m_onTerminate;
2021-08-18 00:36:56 +00:00
struct sigaction m_resizeSignal{};
2021-08-26 01:28:18 +00:00
std::chrono::seconds m_ioTimeOut{1};
int m_fd{0};
static void sigIntHandler(int);
2021-08-18 00:36:56 +00:00
static void sigWinchHandler(int);
2021-08-15 21:31:29 +00:00
public:
/**
* Constructor.
*/
2021-08-18 00:36:56 +00:00
Terminal();
2021-08-15 21:31:29 +00:00
/**
2021-08-18 00:36:56 +00:00
* @brief Destructor.
2021-08-15 21:31:29 +00:00
*/
~Terminal();
2021-08-26 01:28:18 +00:00
/**
* @brief Cleanup
*
* Call this on exit. The destructor will attempt to, but it's not
* guaranteed to actually run correctly that way since we can't predict the
* order in which things are destroyed.
*/
void Cleanup();
/**
* @brief Initialize.
*
* Initializes the terminal for use. You should call this after
* constructing.
*/
void Initialize();
2021-08-18 00:36:56 +00:00
/**
* @brief Processes terminal events.
*
* Checks for ioctl signals, triggers callbacks as-needed.
2021-08-26 01:28:18 +00:00
*/
void ProcessEvents();
/**
* @brief Reads n bytes from terminal input.
2021-08-18 00:36:56 +00:00
*
2021-08-26 01:28:18 +00:00
* @param[in] n How many bytes to read.
* @return Returns the data read from terminal input.
2021-08-18 00:36:56 +00:00
*/
2021-08-26 01:28:18 +00:00
std::wstring Read(size_t n);
2021-08-18 00:36:56 +00:00
2021-08-15 21:31:29 +00:00
/**
* @brief Restores terminal settings back to their original state.
*/
2021-08-26 01:28:18 +00:00
void Restore();
2021-08-15 21:31:29 +00:00
2021-08-18 00:36:56 +00:00
/**
* @brief Sets the on-resize callback function.
*
* This function gets executed when the terminal gets resized.
*
* @param callback Function to be executed when the terminal gets resized.
*/
void SetOnResize(TerminalEventCallback callback);
2021-08-26 01:28:18 +00:00
/**
* @brief Set the on-terminate callback function.
*
* This function gets executed when the terminal gets killed, for instance
* with ctrl+c or a kill command.
*
* If you've got cleanup to run for graceful termination, you should hook
* into this to execute it.
*/
void SetOnTerminate(TerminalEventCallback callback);
2021-08-18 00:36:56 +00:00
/**
* @brief Get the terminal size.
*
* @return Returns the terminal size as a Position with X representing the
* number of columns, and Y the number of rows.
*/
2021-08-26 01:28:18 +00:00
Vector2D Size();
/**
* @brief Get IO timeout.
*
* @return Returns the current I/O timeout.
*/
std::chrono::seconds Timeout() const;
/**
* @brief Set IO timeout.
*
* @param[in] t New IO timeout in seconds.
*/
void Timeout(const std::chrono::seconds& t);
2021-08-18 00:36:56 +00:00
2021-08-15 21:31:29 +00:00
/**
* @brief Disables buffered i/o in the terminal.
*/
2021-08-26 01:28:18 +00:00
void Unbuffer();
/**
* @brief Writes data into the terminal.
* @param data Data to write.
*/
void Write(const std::wstring& data);
2021-08-15 21:31:29 +00:00
};
} // namespace neovision