terminal/src/host/inputBuffer.hpp
PankajBhojwani b3775bc2b0
[Conpty] Pass through request for mouse mode to the Terminal (#9970)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
When the client application sets the console input mode with the `ENABLE_MOUSE_INPUT` flag, we send along the appropriate VT sequences to the connected terminal (if there is one).

<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> 
## References
#376 
#6859 

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [ ] Closes #xxx
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [x] I work here

<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Far manager works
2021-05-07 02:46:11 +00:00

119 lines
4.5 KiB
C++

/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- inputBuffer.hpp
Abstract:
- storage area for incoming input events.
Author:
- Therese Stowell (Thereses) 12-Nov-1990. Adapted from OS/2 subsystem server\srvpipe.c
Revision History:
- Moved from input.h/input.cpp. (AustDi, 2017)
- Refactored to class, added stl container usage (AustDi, 2017)
--*/
#pragma once
#include "inputReadHandleData.h"
#include "readData.hpp"
#include "../types/inc/IInputEvent.hpp"
#include "../server/ObjectHandle.h"
#include "../server/ObjectHeader.h"
#include "../terminal/input/terminalInput.hpp"
#include "../inc/ITerminalOutputConnection.hpp"
#include <deque>
class InputBuffer final : public ConsoleObjectHeader
{
public:
DWORD InputMode;
ConsoleWaitQueue WaitQueue; // formerly ReadWaitQueue
bool fInComposition; // specifies if there's an ongoing text composition
InputBuffer();
~InputBuffer();
// storage API for partial dbcs bytes being read from the buffer
bool IsReadPartialByteSequenceAvailable();
std::unique_ptr<IInputEvent> FetchReadPartialByteSequence(_In_ bool peek);
void StoreReadPartialByteSequence(std::unique_ptr<IInputEvent> event);
// storage API for partial dbcs bytes being written to the buffer
bool IsWritePartialByteSequenceAvailable();
std::unique_ptr<IInputEvent> FetchWritePartialByteSequence(_In_ bool peek);
void StoreWritePartialByteSequence(std::unique_ptr<IInputEvent> event);
void ReinitializeInputBuffer();
void WakeUpReadersWaitingForData();
void TerminateRead(_In_ WaitTerminationReason Flag);
size_t GetNumberOfReadyEvents() const noexcept;
void Flush();
void FlushAllButKeys();
[[nodiscard]] NTSTATUS Read(_Out_ std::deque<std::unique_ptr<IInputEvent>>& OutEvents,
const size_t AmountToRead,
const bool Peek,
const bool WaitForData,
const bool Unicode,
const bool Stream);
[[nodiscard]] NTSTATUS Read(_Out_ std::unique_ptr<IInputEvent>& inEvent,
const bool Peek,
const bool WaitForData,
const bool Unicode,
const bool Stream);
size_t Prepend(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents);
size_t Write(_Inout_ std::unique_ptr<IInputEvent> inEvent);
size_t Write(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents);
bool IsInVirtualTerminalInputMode() const;
Microsoft::Console::VirtualTerminal::TerminalInput& GetTerminalInput();
void SetTerminalConnection(_In_ Microsoft::Console::ITerminalOutputConnection* const pTtyConnection);
void PassThroughWin32MouseRequest(bool enable);
private:
std::deque<std::unique_ptr<IInputEvent>> _storage;
std::unique_ptr<IInputEvent> _readPartialByteSequence;
std::unique_ptr<IInputEvent> _writePartialByteSequence;
Microsoft::Console::VirtualTerminal::TerminalInput _termInput;
Microsoft::Console::ITerminalOutputConnection* _pTtyConnection;
// This flag is used in _HandleTerminalInputCallback
// If the InputBuffer leads to a _HandleTerminalInputCallback call,
// we should suppress the wakeup functions.
// Otherwise, we should be calling them.
bool _vtInputShouldSuppress{ false };
void _ReadBuffer(_Out_ std::deque<std::unique_ptr<IInputEvent>>& outEvents,
const size_t readCount,
_Out_ size_t& eventsRead,
const bool peek,
_Out_ bool& resetWaitEvent,
const bool unicode,
const bool streamRead);
void _WriteBuffer(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inRecords,
_Out_ size_t& eventsWritten,
_Out_ bool& setWaitEvent);
bool _CanCoalesce(const KeyEvent& a, const KeyEvent& b) const noexcept;
bool _CoalesceMouseMovedEvents(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents);
bool _CoalesceRepeatedKeyPressEvents(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents);
void _HandleConsoleSuspensionEvents(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents);
void _HandleTerminalInputCallback(_In_ std::deque<std::unique_ptr<IInputEvent>>& inEvents);
#ifdef UNIT_TESTING
friend class InputBufferTests;
#endif
};