Repository: microsoft/terminal
File: src/host/inputBuffer.cpp (C++)

Code before:
// - None
// Return Value:
// - None
// Note:
// - The console lock must be held when calling this routine.
void InputBuffer::FlushAllButKeys()
{
    auto newEnd = std::remove_if(_storage.begin(), _storage.end(), [](const std::unique_ptr<IInputEvent>& event) {
        return event->EventType() != InputEventType::KeyEvent;
    });
    _storage.erase(newEnd, _storage.end());
}

void InputBuffer::SetTerminalConnection(_In_ ITerminalOutputConnection* const pTtyConnection)
{
    this->_pTtyConnection = pTtyConnection;
}

void InputBuffer::PassThroughWin32MouseRequest(bool enable)
{
    if (_pTtyConnection)
    {
        if (enable)
        {
            LOG_IF_FAILED(_pTtyConnection->WriteTerminalW(L"\x1b[?1003h"));
            LOG_IF_FAILED(_pTtyConnection->WriteTerminalW(L"\x1b[?1006h"));
        }
        else
        {
            LOG_IF_FAILED(_pTtyConnection->WriteTerminalW(L"\x1b[?1003l"));
            LOG_IF_FAILED(_pTtyConnection->WriteTerminalW(L"\x1b[?1006l"));
        }
    }
}

// Routine Description:
// - This routine reads from the input buffer.
// - It can convert returned data to through the currently set Input CP, it can optionally return a wait condition
//   if there isn't enough data in the buffer, and it can be set to not remove records as it reads them out.
// Note:
// - The console lock must be held when calling this routine.
// Arguments:
// - OutEvents - deque to store the read events
// - AmountToRead - the amount of events to try to read
// - Peek - If true, copy events to pInputRecord but don't remove them from the input buffer.
// - WaitForData - if true, wait until an event is input (if there aren't enough to fill client buffer). if false, return immediately
// - Unicode - true if the data in key events should be treated as unicode. false if they should be converted by the current input CP.
// - Stream - true if read should unpack KeyEvents that have a >1 repeat count. AmountToRead must be 1 if Stream is true.
// Return Value:
// - STATUS_SUCCESS if records were read into the client buffer and everything is OK.
// - CONSOLE_STATUS_WAIT if there weren't enough records to satisfy the request (and waits are allowed)

Review comment (bug):
You could probably put these in one request! Since we support DECSET with multiple parameters...

```suggestion
            LOG_IF_FAILED(_pTtyConnection->WriteTerminalW(L"\x1b[?1003;1006h"));
```

(I checked xterm- it looks like it supports multiple DECSET/DECRST modes in one mode line? I can't corroborate that with the VT510 manual. @j4james likely knows if this is standards-compliant... he explicitly made it work in #7799!)

Code after:
// - None
// Return Value:
// - None
// Note:
// - The console lock must be held when calling this routine.
void InputBuffer::FlushAllButKeys()
{
    auto newEnd = std::remove_if(_storage.begin(), _storage.end(), [](const std::unique_ptr<IInputEvent>& event) {
        return event->EventType() != InputEventType::KeyEvent;
    });
    _storage.erase(newEnd, _storage.end());
}

void InputBuffer::SetTerminalConnection(_In_ ITerminalOutputConnection* const pTtyConnection)
{
    this->_pTtyConnection = pTtyConnection;
}

void InputBuffer::PassThroughWin32MouseRequest(bool enable)
{
    if (_pTtyConnection)
    {
        if (enable)
        {
            LOG_IF_FAILED(_pTtyConnection->WriteTerminalW(L"\x1b[?1003;1006h"));
        }
        else
        {
            LOG_IF_FAILED(_pTtyConnection->WriteTerminalW(L"\x1b[?1003;1006l"));
        }
    }
}

// Routine Description:
// - This routine reads from the input buffer.
// - It can convert returned data to through the currently set Input CP, it can optionally return a wait condition
//   if there isn't enough data in the buffer, and it can be set to not remove records as it reads them out.
// Note:
// - The console lock must be held when calling this routine.
// Arguments:
// - OutEvents - deque to store the read events
// - AmountToRead - the amount of events to try to read
// - Peek - If true, copy events to pInputRecord but don't remove them from the input buffer.
// - WaitForData - if true, wait until an event is input (if there aren't enough to fill client buffer). if false, return immediately
// - Unicode - true if the data in key events should be treated as unicode. false if they should be converted by the current input CP.
// - Stream - true if read should unpack KeyEvents that have a >1 repeat count. AmountToRead must be 1 if Stream is true.
// Return Value:
// - STATUS_SUCCESS if records were read into the client buffer and everything is OK.
// - CONSOLE_STATUS_WAIT if there weren't enough records to satisfy the request (and waits are allowed)
// - otherwise a suitable memory/math/string error in NTSTATUS form.
[[nodiscard]] NTSTATUS InputBuffer::Read(_Out_ std::deque<std::unique_ptr<IInputEvent>>& OutEvents,