2022-04-03 10:16:20 +02:00
|
|
|
/**
|
|
|
|
* @brief `ncurses` window displaying contents of a pseudo terminal
|
|
|
|
* @author Christian Burger (christian@krikkel.de)
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <cursesw.h>
|
|
|
|
#include <pty.h>
|
|
|
|
#include <vterm.h>
|
|
|
|
#include <string>
|
|
|
|
#include <thread>
|
|
|
|
|
2022-04-05 10:23:50 +02:00
|
|
|
#ifdef add_wch
|
|
|
|
inline void UNDEF(add_wch)(const cchar_t *character) { add_wch(character); }
|
|
|
|
#undef add_wch
|
|
|
|
#define add_wch UNDEF(add_wch)
|
|
|
|
#endif
|
|
|
|
|
2022-04-05 10:28:10 +02:00
|
|
|
namespace krikkel::NCursesPtyWindow
|
2022-04-03 10:16:20 +02:00
|
|
|
{
|
|
|
|
class NCursesPtyWindow : public NCursesWindow
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
NCursesPtyWindow(int lines, int columns, int y, int x);
|
|
|
|
~NCursesPtyWindow();
|
|
|
|
|
|
|
|
int getFdPtyClient() const;
|
2022-04-08 21:35:49 +02:00
|
|
|
void writeToClient(const char * string, size_t length) const;
|
2022-04-03 10:16:20 +02:00
|
|
|
|
2022-04-05 10:23:50 +02:00
|
|
|
int add_wch(cchar_t *character);
|
|
|
|
int refresh() override;
|
2022-04-05 12:34:35 +02:00
|
|
|
int wresize(int rows, int cols);
|
2022-04-05 10:23:50 +02:00
|
|
|
|
2022-04-03 10:16:20 +02:00
|
|
|
private:
|
|
|
|
int fdPtyHost, fdPtyClient;
|
|
|
|
struct termios terminalParameters;
|
|
|
|
VTerm *pseudoTerminal;
|
|
|
|
VTermScreen *pseudoTerminalScreen;
|
|
|
|
static VTermScreenCallbacks screenCallbacks;
|
|
|
|
/// @todo one line is at most 4096 chars long
|
2022-04-07 14:28:35 +02:00
|
|
|
static const size_t PTY_CLIENT_OUTPUT_BUFFER_SIZE = 8192;
|
|
|
|
char ptyClientOutputBuffer[PTY_CLIENT_OUTPUT_BUFFER_SIZE];
|
2022-04-05 10:23:50 +02:00
|
|
|
uint16_t cursorX, cursorY;
|
2022-04-03 10:16:20 +02:00
|
|
|
|
|
|
|
std::thread readPtyClientThread;
|
|
|
|
void readFromPtyClientThreadMethod();
|
|
|
|
void readFromPtyClient();
|
|
|
|
|
|
|
|
int handlerDamage(VTermRect rect);
|
|
|
|
int handlerMoveRect(VTermRect dest, VTermRect src);
|
|
|
|
int handlerMoveCursor(VTermPos pos, VTermPos oldpos, int visible);
|
|
|
|
int handlerSetTermProp(VTermProp prop, VTermValue *val);
|
|
|
|
int handlerBell();
|
|
|
|
int handlerResize(int rows, int cols);
|
|
|
|
int handlerPushLine(int cols, const VTermScreenCell *cells);
|
|
|
|
int handlerPopLine(int cols, VTermScreenCell *cells);
|
|
|
|
|
2022-04-05 10:23:50 +02:00
|
|
|
attr_t extractAttributesFromVTermCell(VTermScreenCell cell);
|
|
|
|
short extractColorFromVTermCell(VTermScreenCell cell);
|
2022-04-03 10:16:20 +02:00
|
|
|
void copyPtyCellToNCursesWindow(int x, int y);
|
|
|
|
|
|
|
|
static int staticHandlerDamage(VTermRect rect, void *user);
|
|
|
|
static int staticHandlerMoveRect(VTermRect dest, VTermRect src, void *user);
|
|
|
|
static int staticHandlerMoveCursor(VTermPos pos, VTermPos oldpos, int visible, void *user);
|
|
|
|
static int staticHandlerSetTermProp(VTermProp prop, VTermValue *val, void *user);
|
|
|
|
static int staticHandlerBell(void *user);
|
|
|
|
static int staticHandlerResize(int rows, int cols, void *user);
|
|
|
|
static int staticHandlerPushLine(int cols, const VTermScreenCell *cells, void *user);
|
|
|
|
static int staticHandlerPopLine(int cols, VTermScreenCell *cells, void *user);
|
2022-04-08 21:35:49 +02:00
|
|
|
static void staticHandlerOutput(const char *s, size_t len, void *user);
|
|
|
|
};
|
2022-04-03 10:16:20 +02:00
|
|
|
}
|