From 6e86a4972b601f2fba2adde9891b0822ddc74f6c Mon Sep 17 00:00:00 2001 From: Ivan Sorokin Date: Fri, 31 Mar 2023 18:11:40 +0200 Subject: [PATCH] support win32-input-mode --- .../Backend/TTY/TTYInputSequenceParser.cpp | 22 +++++ WinPort/src/Backend/TTY/TTYOutput.cpp | 2 + far2l/src/vt/IVTShell.h | 1 + far2l/src/vt/vtansi.cpp | 5 ++ far2l/src/vt/vtshell.cpp | 86 ++++++++++++------- 5 files changed, 86 insertions(+), 30 deletions(-) diff --git a/WinPort/src/Backend/TTY/TTYInputSequenceParser.cpp b/WinPort/src/Backend/TTY/TTYInputSequenceParser.cpp index 5cb1a3cec..480f8dec9 100644 --- a/WinPort/src/Backend/TTY/TTYInputSequenceParser.cpp +++ b/WinPort/src/Backend/TTY/TTYInputSequenceParser.cpp @@ -311,6 +311,28 @@ void TTYInputSequenceParser::ParseAPC(const char *s, size_t l) size_t TTYInputSequenceParser::ParseEscapeSequence(const char *s, size_t l) { + if (s[0] == '[' && s[l-1] == '_') { + + // win32-input-mode sequence + + INPUT_RECORD ir = {}; + ir.EventType = KEY_EVENT; + + int a = 0, b = 0, c = 0, d = 0, e = 0, f = 0; + sscanf(s, "[%d;%d;%d;%d;%d;%d_", &a, &b, &c, &d, &e, &f); + + ir.Event.KeyEvent.wVirtualKeyCode = a; + ir.Event.KeyEvent.wVirtualScanCode = b; + ir.Event.KeyEvent.uChar.UnicodeChar = c; + ir.Event.KeyEvent.bKeyDown = d; + ir.Event.KeyEvent.dwControlKeyState = e; + ir.Event.KeyEvent.wRepeatCount = f; + + _ir_pending.emplace_back(ir); // g_winport_con_in->Enqueue(&ir, 1); + + return l; + } + if (l > 2 && s[0] == '[' && s[2] == 'n') { return 3; } diff --git a/WinPort/src/Backend/TTY/TTYOutput.cpp b/WinPort/src/Backend/TTY/TTYOutput.cpp index 476011887..9226e51cf 100644 --- a/WinPort/src/Backend/TTY/TTYOutput.cpp +++ b/WinPort/src/Backend/TTY/TTYOutput.cpp @@ -162,6 +162,7 @@ TTYOutput::TTYOutput(int out, bool far2l_tty) #endif Format(ESC "7" ESC "[?47h" ESC "[?1049h" ESC "[?2004h"); + Format(ESC "[?9001h"); // win32-input-mode on ChangeKeypad(true); ChangeMouse(true); @@ -186,6 +187,7 @@ TTYOutput::~TTYOutput() Format(ESC "[0 q"); } Format(ESC "[0m" ESC "[?1049l" ESC "[?47l" ESC "8" ESC "[?2004l" "\r\n"); + Format(ESC "[?9001l"); // win32-input-mode off TTYBasePalette def_palette; ChangePalette(def_palette); Flush(); diff --git a/far2l/src/vt/IVTShell.h b/far2l/src/vt/IVTShell.h index c20163203..a2bd77d99 100644 --- a/far2l/src/vt/IVTShell.h +++ b/far2l/src/vt/IVTShell.h @@ -16,6 +16,7 @@ struct IVTShell { virtual void OnMouseExpectation(MouseExpectation mex) = 0; virtual void OnBracketedPasteExpectation(bool enabled) = 0; + virtual void OnWin32InputMode(bool enabled) = 0; virtual void OnApplicationProtocolCommand(const char *str) = 0; virtual bool OnOSCommand(int id, std::string &str) = 0; virtual void InjectInput(const char *str) = 0; diff --git a/far2l/src/vt/vtansi.cpp b/far2l/src/vt/vtansi.cpp index 6d99aad59..b0336cad6 100644 --- a/far2l/src/vt/vtansi.cpp +++ b/far2l/src/vt/vtansi.cpp @@ -722,6 +722,11 @@ void InterpretEscSeq( void ) g_vt_shell->OnBracketedPasteExpectation(suffix == 'h'); break; + case 9001: + if (g_vt_shell) + g_vt_shell->OnWin32InputMode(suffix == 'h'); + break; + case 1049: g_alternative_screen_buffer.Toggle(suffix == 'h'); break; diff --git a/far2l/src/vt/vtshell.cpp b/far2l/src/vt/vtshell.cpp index 6990960e3..56d22b734 100644 --- a/far2l/src/vt/vtshell.cpp +++ b/far2l/src/vt/vtshell.cpp @@ -79,6 +79,7 @@ class VTShell : VTOutputReader::IProcessor, VTInputReader::IProcessor, IVTShell std::string _slavename; std::atomic _keypad{0}; std::atomic _bracketed_paste_expected{false}; + std::atomic _win32_input_mode_expected{false}; INPUT_RECORD _last_window_info_ir; std::unique_ptr _far2l_exts; std::unique_ptr _mouse; @@ -386,11 +387,12 @@ class VTShell : VTOutputReader::IProcessor, VTInputReader::IProcessor, IVTShell return; } - if (!KeyEvent.bKeyDown) - return; - DWORD dw; const std::string &translated = TranslateKeyEvent(KeyEvent); + + if (!KeyEvent.bKeyDown && !_win32_input_mode_expected) + return; + if (!translated.empty()) { if (_slavename.empty() && KeyEvent.uChar.UnicodeChar) {//pipes fallback WINPORT(WriteConsole)( NULL, &KeyEvent.uChar.UnicodeChar, 1, &dw, NULL ); @@ -489,6 +491,11 @@ class VTShell : VTOutputReader::IProcessor, VTInputReader::IProcessor, IVTShell _bracketed_paste_expected = enabled; } + virtual void OnWin32InputMode(bool enabled) + { + _win32_input_mode_expected = enabled; + } + virtual void OnApplicationProtocolCommand(const char *str)//NB: called not from main thread! { if (strncmp(str, "far2l", 5) == 0) { @@ -655,39 +662,58 @@ class VTShell : VTOutputReader::IProcessor, VTInputReader::IProcessor, IVTShell std::string TranslateKeyEvent(const KEY_EVENT_RECORD &KeyEvent) { if (KeyEvent.wVirtualKeyCode) { + const bool ctrl = (KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) != 0; const bool alt = (KeyEvent.dwControlKeyState & (RIGHT_ALT_PRESSED|LEFT_ALT_PRESSED)) != 0; const bool shift = (KeyEvent.dwControlKeyState & (SHIFT_PRESSED)) != 0; - - if (!ctrl && !shift && !alt && KeyEvent.wVirtualKeyCode==VK_BACK) { - //WCM has a setting for that, so probably in some cases backspace should be returned as is - char backspace[] = {127, 0}; - return backspace; - } - - if ((ctrl && shift && !alt && KeyEvent.wVirtualKeyCode=='V') || - (!ctrl && shift && !alt && KeyEvent.wVirtualKeyCode==VK_INSERT) ) { - return StringFromClipboard(); - } - - if (ctrl && !shift && KeyEvent.wVirtualKeyCode=='C') { - OnCtrlC(alt); - } - - if (ctrl && !shift && alt && KeyEvent.wVirtualKeyCode=='Z') { - WINPORT(ConsoleBackgroundMode)(TRUE); - return ""; + + if (KeyEvent.bKeyDown) { + + if (!ctrl && !shift && !alt && KeyEvent.wVirtualKeyCode==VK_BACK) { + //WCM has a setting for that, so probably in some cases backspace should be returned as is + char backspace[] = {127, 0}; + return backspace; + } + + if ((ctrl && shift && !alt && KeyEvent.wVirtualKeyCode=='V') || + (!ctrl && shift && !alt && KeyEvent.wVirtualKeyCode==VK_INSERT) ) { + return StringFromClipboard(); + } + + if (ctrl && !shift && KeyEvent.wVirtualKeyCode=='C') { + OnCtrlC(alt); + } + + if (ctrl && !shift && alt && KeyEvent.wVirtualKeyCode=='Z') { + WINPORT(ConsoleBackgroundMode)(TRUE); + return ""; + } + + if (ctrl && shift && KeyEvent.wVirtualKeyCode==VK_F4) { + OnConsoleLog(CLK_EDIT); + return ""; + } + + if (ctrl && shift && KeyEvent.wVirtualKeyCode==VK_F3) { + OnConsoleLog(CLK_VIEW); + return ""; + } } - if (ctrl && shift && KeyEvent.wVirtualKeyCode==VK_F4) { - OnConsoleLog(CLK_EDIT); - return ""; - } + if (_win32_input_mode_expected) { + char buffer[64]; + sprintf(buffer, "\x1B[%i;%i;%i;%i;%i;%i_", + KeyEvent.wVirtualKeyCode, + KeyEvent.wVirtualScanCode, + KeyEvent.uChar.UnicodeChar, + KeyEvent.bKeyDown, + KeyEvent.dwControlKeyState, + KeyEvent.wRepeatCount + ); + return buffer; + } - if (ctrl && shift && KeyEvent.wVirtualKeyCode==VK_F3) { - OnConsoleLog(CLK_VIEW); - return ""; - } + if (!KeyEvent.bKeyDown) { return ""; } const char *spec = VT_TranslateSpecialKey( KeyEvent.wVirtualKeyCode, ctrl, alt, shift, _keypad, KeyEvent.uChar.UnicodeChar);