Factor some input handling out of Agent/Win32Console into ConsoleInput

This commit is contained in:
Ryan Prichard 2016-05-25 21:09:22 -05:00
parent ab26c8b0d0
commit 6a253ee5a8
6 changed files with 45 additions and 65 deletions

View File

@ -190,8 +190,9 @@ Agent::Agent(LPCWSTR controlPipeName,
setupPacket.putWString(m_conoutPipe->name());
writePacket(setupPacket);
const HANDLE conin = GetStdHandle(STD_INPUT_HANDLE);
m_terminal.reset(new Terminal(*m_conoutPipe));
m_consoleInput.reset(new ConsoleInput(*this));
m_consoleInput.reset(new ConsoleInput(conin, *this));
resetConsoleTracking(Terminal::OmitClear, m_console->windowRect());
@ -206,16 +207,15 @@ Agent::Agent(LPCWSTR controlPipeName,
// console, and I think it's better to default it off for the sake of
// programs that care about mouse input.
DWORD mode = 0;
if (!GetConsoleMode(m_console->conin(), &mode)) {
if (!GetConsoleMode(conin, &mode)) {
trace("Agent startup: GetConsoleMode failed");
} else {
mode &= ~ENABLE_QUICK_EDIT_MODE;
if (!SetConsoleMode(m_console->conin(), mode)) {
if (!SetConsoleMode(conin, mode)) {
trace("Agent startup: SetConsoleMode failed");
}
}
updateMouseInputFlags(true);
setPollInterval(25);
}
@ -461,28 +461,10 @@ void Agent::pollConoutPipe()
}
}
void Agent::updateMouseInputFlags(bool forceTrace)
{
DWORD mode = 0;
GetConsoleMode(m_console->conin(), &mode);
const bool newFlagMI = mode & ENABLE_MOUSE_INPUT;
const bool newFlagQE = mode & ENABLE_QUICK_EDIT_MODE;
if (forceTrace ||
newFlagMI != m_consoleMouseInputEnabled ||
newFlagQE != m_consoleQuickEditEnabled) {
trace("CONIN mode: ENABLE_MOUSE_INPUT=%s ENABLE_QUICK_EDIT_MODE=%s",
newFlagMI ? "enabled" : "disabled",
newFlagQE ? "enabled" : "disabled");
}
m_consoleMouseInputEnabled = newFlagMI;
m_consoleQuickEditEnabled = newFlagQE;
m_consoleInput->setMouseInputEnabled(newFlagMI && !newFlagQE);
}
void Agent::onPollTimeout()
{
// Check the mouse input flag so we can output a trace message.
updateMouseInputFlags();
m_consoleInput->updateMouseInputFlags();
// Give the ConsoleInput object a chance to flush input from an incomplete
// escape sequence (e.g. pressing ESC).

View File

@ -74,7 +74,6 @@ private:
void handleSetSizePacket(ReadBuffer &packet);
void pollConinPipe();
void pollConoutPipe();
void updateMouseInputFlags(bool forceTrace=false);
protected:
virtual void onPollTimeout();
@ -100,8 +99,6 @@ private:
private:
bool m_useMark = false;
std::unique_ptr<Win32Console> m_console;
bool m_consoleMouseInputEnabled = false;
bool m_consoleQuickEditEnabled = false;
NamedPipe *m_controlPipe = nullptr;
NamedPipe *m_coninPipe = nullptr;
NamedPipe *m_conoutPipe = nullptr;

View File

@ -209,14 +209,15 @@ static int utf8CharLength(char firstByte)
} // anonymous namespace
ConsoleInput::ConsoleInput(DsrSender &dsrSender) :
m_console(new Win32Console),
ConsoleInput::ConsoleInput(HANDLE conin, DsrSender &dsrSender) :
m_conin(conin),
m_dsrSender(dsrSender)
{
addDefaultEntriesToInputMap(m_inputMap);
if (hasDebugFlag("dump_input_map")) {
m_inputMap.dumpInputMap();
}
updateMouseInputFlags(true);
}
void ConsoleInput::writeInput(const std::string &input)
@ -273,6 +274,22 @@ void ConsoleInput::flushIncompleteEscapeCode()
}
}
void ConsoleInput::updateMouseInputFlags(bool forceTrace)
{
const DWORD mode = inputConsoleMode();
const bool newFlagMI = mode & ENABLE_MOUSE_INPUT;
const bool newFlagQE = mode & ENABLE_QUICK_EDIT_MODE;
if (forceTrace ||
newFlagMI != m_mouseInputEnabled ||
newFlagQE != m_quickEditEnabled) {
trace("CONIN mode: ENABLE_MOUSE_INPUT=%s ENABLE_QUICK_EDIT_MODE=%s",
newFlagMI ? "enabled" : "disabled",
newFlagQE ? "enabled" : "disabled");
}
m_mouseInputEnabled = newFlagMI;
m_quickEditEnabled = newFlagQE;
}
void ConsoleInput::doWrite(bool isEof)
{
const char *data = m_byteQueue.c_str();
@ -285,7 +302,10 @@ void ConsoleInput::doWrite(bool isEof)
idx += charSize;
}
m_byteQueue.erase(0, idx);
m_console->writeInput(records.data(), records.size());
DWORD actual = 0;
if (!WriteConsoleInput(m_conin, records.data(), records.size(), &actual)) {
trace("WriteConsoleInput failed");
}
}
int ConsoleInput::scanInput(std::vector<INPUT_RECORD> &records,
@ -296,7 +316,7 @@ int ConsoleInput::scanInput(std::vector<INPUT_RECORD> &records,
ASSERT(inputSize >= 1);
// Ctrl-C.
if (input[0] == '\x03' && m_console->processedInputMode()) {
if (input[0] == '\x03' && (inputConsoleMode() & ENABLE_PROCESSED_INPUT)) {
trace("Ctrl-C");
BOOL ret = GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
trace("GenerateConsoleCtrlEvent: %d", ret);
@ -467,7 +487,7 @@ int ConsoleInput::scanMouseInput(std::vector<INPUT_RECORD> &records,
mer.dwButtonState |= m_mouseButtonState;
if (m_mouseInputEnabled) {
if (m_mouseInputEnabled && !m_quickEditEnabled) {
if (isTracingEnabled()) {
static bool debugInput = hasDebugFlag("input");
if (debugInput) {
@ -584,3 +604,13 @@ void ConsoleInput::appendInputRecord(std::vector<INPUT_RECORD> &records,
ir.Event.KeyEvent.dwControlKeyState = keyState;
records.push_back(ir);
}
DWORD ConsoleInput::inputConsoleMode()
{
DWORD mode = 0;
if (!GetConsoleMode(m_conin, &mode)) {
trace("GetConsoleMode failed");
return 0;
}
return mode;
}

View File

@ -38,11 +38,11 @@ class DsrSender;
class ConsoleInput
{
public:
ConsoleInput(DsrSender &dsrSender);
ConsoleInput(HANDLE conin, DsrSender &dsrSender);
void writeInput(const std::string &input);
void flushIncompleteEscapeCode();
void setMouseInputEnabled(bool val) { m_mouseInputEnabled = val; }
void setMouseWindowRect(SmallRect val) { m_mouseWindowRect = val; }
void updateMouseInputFlags(bool forceTrace=false);
private:
void doWrite(bool isEof);
@ -66,9 +66,10 @@ private:
uint16_t virtualKey,
uint16_t unicodeChar,
uint16_t keyState);
DWORD inputConsoleMode();
private:
std::unique_ptr<Win32Console> m_console;
HANDLE m_conin = nullptr;
DsrSender &m_dsrSender;
bool m_dsrSent = false;
std::string m_byteQueue;
@ -82,6 +83,7 @@ private:
bool released = false;
} m_doubleClick;
bool m_mouseInputEnabled = false;
bool m_quickEditEnabled = false;
SmallRect m_mouseWindowRect;
};

View File

@ -30,7 +30,6 @@
Win32Console::Win32Console() : m_titleWorkBuf(16)
{
m_conin = GetStdHandle(STD_INPUT_HANDLE);
m_conout = CreateFileW(L"CONOUT$",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
@ -43,11 +42,6 @@ Win32Console::~Win32Console()
CloseHandle(m_conout);
}
HANDLE Win32Console::conin()
{
return m_conin;
}
HANDLE Win32Console::conout()
{
return m_conout;
@ -132,25 +126,6 @@ void Win32Console::setCursorPosition(const Coord &coord)
}
}
void Win32Console::writeInput(const INPUT_RECORD *ir, int count)
{
// TODO: error handling
DWORD dummy = 0;
if (!WriteConsoleInput(m_conin, ir, count, &dummy)) {
trace("WriteConsoleInput failed");
}
}
bool Win32Console::processedInputMode()
{
// TODO: error handling
DWORD mode = 0;
if (!GetConsoleMode(m_conin, &mode)) {
trace("GetConsoleMode failed");
}
return (mode & ENABLE_PROCESSED_INPUT) == ENABLE_PROCESSED_INPUT;
}
void Win32Console::read(const SmallRect &rect, CHAR_INFO *data)
{
// TODO: error handling

View File

@ -48,7 +48,6 @@ public:
Win32Console();
~Win32Console();
HANDLE conin();
HANDLE conout();
HWND hwnd();
void clearLines(int row, int count, const ConsoleScreenBufferInfo &info);
@ -65,10 +64,6 @@ public:
Coord cursorPosition();
void setCursorPosition(const Coord &point);
// Input stream.
void writeInput(const INPUT_RECORD *ir, int count=1);
bool processedInputMode();
// Screen content.
void read(const SmallRect &rect, CHAR_INFO *data);
void write(const SmallRect &rect, const CHAR_INFO *data);
@ -80,7 +75,6 @@ public:
void setTextAttribute(WORD attributes);
private:
HANDLE m_conin;
HANDLE m_conout;
std::vector<wchar_t> m_titleWorkBuf;
};