Skip to content

Commit

Permalink
Far2lTTY: new input notification about terminal size (fix #1856)
Browse files Browse the repository at this point in the history
  • Loading branch information
elfmz committed Oct 1, 2023
1 parent 0fcaa60 commit beefe74
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 22 deletions.
11 changes: 11 additions & 0 deletions WinPort/FarTTY.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,12 @@ All integer values are in little-endian format.
*/
#define FARTTY_FEAT_COMPACT_INPUT 0x00000001

/** Client may specify this wanted extra feature if it supports in-band terminal size events.
If server supports this feature it may send such events, however client should be ready to
handle usual SIGWINCH signals as well.
*/
#define FARTTY_FEAT_TERMINAL_SIZE 0x00000002

/** Server reports this on responce of FARTTY_INTERRACT_CLIP_OPEN if it supports clipboard data ID.
Clipboard data ID allows client-side caching of clipboard data to avoid known data transfers.
*/
Expand Down Expand Up @@ -291,3 +297,8 @@ all arguments are defined by FARTTY_INPUT_* notification ID - see below (stack t
#define FARTTY_INPUT_KEYDOWN_COMPACT 'C'
#define FARTTY_INPUT_KEYUP_COMPACT 'c'

/** Server sends this to inform about recent terminal size.
uint16_t (terminal width)
uint16_t (terminal height)
*/
#define FARTTY_INPUT_TERMINAL_SIZE 'S'
46 changes: 27 additions & 19 deletions WinPort/src/Backend/TTY/TTYBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "FarTTY.h"
#include "../FSClipboardBackend.h"

static uint16_t g_far2l_term_width = 80, g_far2l_term_height = 25;
static volatile long s_terminal_size_change_id = 0;
static TTYBackend * g_vtb = nullptr;

Expand Down Expand Up @@ -100,9 +101,8 @@ TTYBackend::TTYBackend(const char *full_exe_path, int std_in, int std_out, bool
}

struct winsize w{};
if (GetWinSize(w)) {
g_winport_con_out->SetSize(w.ws_col, w.ws_row);
}
GetWinSize(w);
g_winport_con_out->SetSize(w.ws_col, w.ws_row);
g_winport_con_out->GetSize(_cur_width, _cur_height);
g_vtb = this;
}
Expand All @@ -128,18 +128,17 @@ TTYBackend::~TTYBackend()
DetachNotifyPipe();
}

bool TTYBackend::GetWinSize(struct winsize &w)
void TTYBackend::GetWinSize(struct winsize &w)
{
int r = ioctl(_stdout, TIOCGWINSZ, &w);
if (UNLIKELY(r != 0)) {
r = ioctl(_stdin, TIOCGWINSZ, &w);
if (UNLIKELY(r != 0)) {
perror("GetWinSize");
return false;
perror("TIOCGWINSZ");
w.ws_row = g_far2l_term_height;
w.ws_col = g_far2l_term_width;
}
}

return true;
}

void TTYBackend::DetachNotifyPipe()
Expand Down Expand Up @@ -461,9 +460,7 @@ void TTYBackend::DispatchPalette(TTYOutput &tty_out)
void TTYBackend::DispatchTermResized(TTYOutput &tty_out)
{
struct winsize w{};
if (!GetWinSize(w)) {
return;
}
GetWinSize(w);

if (_cur_width != w.ws_col || _cur_height != w.ws_row) {
g_winport_con_out->SetSize(w.ws_col, w.ws_row);
Expand Down Expand Up @@ -908,6 +905,14 @@ bool TTYBackend::OnConsoleIsActive()
return false;//true;
}

void TTYBackend_OnTerminalDamaged(bool flush_input_queue)
{
__sync_add_and_fetch ( &s_terminal_size_change_id, 1);
if (g_vtb) {
g_vtb->KickAss(flush_input_queue);
}
}

static void OnFar2lKey(bool down, StackSerializer &stk_ser)
{
try {
Expand All @@ -927,6 +932,13 @@ static void OnFar2lKey(bool down, StackSerializer &stk_ser)
}
}

static void OnFar2lTerminalSize(StackSerializer &stk_ser)
{
stk_ser.PopNum(g_far2l_term_height);
stk_ser.PopNum(g_far2l_term_width);
TTYBackend_OnTerminalDamaged(false);
}

static void OnFar2lKeyCompact(bool down, StackSerializer &stk_ser)
{
try {
Expand Down Expand Up @@ -1026,6 +1038,10 @@ void TTYBackend::OnFar2lEvent(StackSerializer &stk_ser)
OnFar2lKeyCompact(code == FARTTY_INPUT_KEYDOWN_COMPACT, stk_ser);
break;

case FARTTY_INPUT_TERMINAL_SIZE:
OnFar2lTerminalSize(stk_ser);
break;

default:
fprintf(stderr, "Far2lEvent unknown code=0x%x!\n", (unsigned int)(unsigned char)code);
}
Expand Down Expand Up @@ -1149,14 +1165,6 @@ bool TTYBackend::OnConsoleBackgroundMode(bool TryEnterBackgroundMode)
}


void TTYBackend_OnTerminalDamaged(bool flush_input_queue)
{
__sync_add_and_fetch ( &s_terminal_size_change_id, 1);
if (g_vtb) {
g_vtb->KickAss(flush_input_queue);
}
}

static void OnSigWinch(int)
{
TTYBackend_OnTerminalDamaged(false);
Expand Down
2 changes: 1 addition & 1 deletion WinPort/src/Backend/TTY/TTYBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class TTYBackend : IConsoleOutputBackend, ITTYInputSpecialSequenceHandler, IFar2

ClipboardBackendSetter _clipboard_backend_setter;

bool GetWinSize(struct winsize &w);
void GetWinSize(struct winsize &w);
void ChooseSimpleClipboardBackend();
void DispatchTermResized(TTYOutput &tty_out);
void DispatchOutput(TTYOutput &tty_out);
Expand Down
6 changes: 5 additions & 1 deletion WinPort/src/Backend/TTY/TTYOutput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,12 @@ TTYOutput::TTYOutput(int out, bool far2l_tty, bool norgb)
ChangeMouse(true);

if (far2l_tty) {
uint64_t wanted_feats = FARTTY_FEAT_COMPACT_INPUT;
if (!isatty(_out)) {
wanted_feats|= FARTTY_FEAT_TERMINAL_SIZE;
}
StackSerializer stk_ser;
stk_ser.PushNum((uint64_t)(FARTTY_FEAT_COMPACT_INPUT));
stk_ser.PushNum(wanted_feats);
stk_ser.PushNum(FARTTY_INTERRACT_CHOOSE_EXTRA_FEATURES);
stk_ser.PushNum((uint8_t)0); // zero ID means not expecting reply
SendFar2lInterract(stk_ser);
Expand Down
18 changes: 18 additions & 0 deletions far2l/src/vt/VTFar2lExtensios.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,21 @@ void VTFar2lExtensios::AllowClipboardRead(bool prolong)

///

void VTFar2lExtensios::OnTerminalResized()
{
if ( (_xfeatures & FARTTY_FEAT_TERMINAL_SIZE) != 0) {
CONSOLE_SCREEN_BUFFER_INFO csbi = { };
if (WINPORT(GetConsoleScreenBufferInfo)( NULL, &csbi )
&& csbi.dwSize.X && csbi.dwSize.Y) {
StackSerializer stk_ser;
stk_ser.PushNum((uint16_t)csbi.dwSize.X);
stk_ser.PushNum((uint16_t)csbi.dwSize.Y);
stk_ser.PushNum(FARTTY_INPUT_TERMINAL_SIZE);
WriteInputEvent(stk_ser);
}
}
}

bool VTFar2lExtensios::OnInputMouse(const MOUSE_EVENT_RECORD &MouseEvent)
{
if (MouseEvent.dwButtonState & FROM_LEFT_2ND_BUTTON_PRESSED) {
Expand Down Expand Up @@ -554,6 +569,9 @@ void VTFar2lExtensios::OnInterract(StackSerializer &stk_ser)
_xfeatures = 0;
stk_ser.PopNum(_xfeatures);
stk_ser.Clear();
if (_xfeatures & FARTTY_FEAT_TERMINAL_SIZE) {
OnTerminalResized();
}
break;

case FARTTY_INTERRACT_CONSOLE_ADHOC_QEDIT:
Expand Down
1 change: 1 addition & 0 deletions far2l/src/vt/VTFar2lExtensios.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class VTFar2lExtensios
VTFar2lExtensios(IVTShell *vt_shell, const std::string &host_id);
~VTFar2lExtensios();

void OnTerminalResized();
bool OnInputMouse(const MOUSE_EVENT_RECORD &MouseEvent);
bool OnInputKey(const KEY_EVENT_RECORD &KeyEvent);
void OnInterract(StackSerializer &stk_ser);
Expand Down
8 changes: 7 additions & 1 deletion far2l/src/vt/vtshell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ class VTShell : VTOutputReader::IProcessor, VTInputReader::IProcessor, IVTShell
void UpdateTerminalSize(int fd_term)
{
CONSOLE_SCREEN_BUFFER_INFO csbi = { };
if (WINPORT(GetConsoleScreenBufferInfo)( NULL, &csbi )
if (WINPORT(GetConsoleScreenBufferInfo)( NULL, &csbi )
&& csbi.dwSize.X && csbi.dwSize.Y) {
fprintf(stderr, "UpdateTerminalSize: %u x %u\n", csbi.dwSize.X, csbi.dwSize.Y);
struct winsize ws = {(unsigned short)csbi.dwSize.Y,
Expand Down Expand Up @@ -346,6 +346,8 @@ class VTShell : VTOutputReader::IProcessor, VTInputReader::IProcessor, IVTShell
{
if (!_slavename.empty())
UpdateTerminalSize(_fd_out);
if (_far2l_exts)
_far2l_exts->OnTerminalResized();
}

virtual void OnInputResized(const INPUT_RECORD &ir) //called from worker thread
Expand Down Expand Up @@ -496,6 +498,8 @@ class VTShell : VTOutputReader::IProcessor, VTInputReader::IProcessor, IVTShell

if (!_slavename.empty())
UpdateTerminalSize(_fd_out);
if (_far2l_exts)
_far2l_exts->OnTerminalResized();
}

virtual void OnKeypadChange(unsigned char keypad)
Expand Down Expand Up @@ -843,6 +847,8 @@ class VTShell : VTOutputReader::IProcessor, VTInputReader::IProcessor, IVTShell

if (!_slavename.empty())
UpdateTerminalSize(_fd_out);
if (_far2l_exts)
_far2l_exts->OnTerminalResized();

std::string cmd_str;
if (!_slavename.empty()) {
Expand Down

0 comments on commit beefe74

Please sign in to comment.