/*++ 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 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 FetchReadPartialByteSequence(_In_ bool peek); void StoreReadPartialByteSequence(std::unique_ptr event); // storage API for partial dbcs bytes being written to the buffer bool IsWritePartialByteSequenceAvailable(); std::unique_ptr FetchWritePartialByteSequence(_In_ bool peek); void StoreWritePartialByteSequence(std::unique_ptr 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>& OutEvents, const size_t AmountToRead, const bool Peek, const bool WaitForData, const bool Unicode, const bool Stream); [[nodiscard]] NTSTATUS Read(_Out_ std::unique_ptr& inEvent, const bool Peek, const bool WaitForData, const bool Unicode, const bool Stream); size_t Prepend(_Inout_ std::deque>& inEvents); size_t Write(_Inout_ std::unique_ptr inEvent); size_t Write(_Inout_ std::deque>& inEvents); bool IsInVirtualTerminalInputMode() const; Microsoft::Console::VirtualTerminal::TerminalInput& GetTerminalInput(); private: std::deque> _storage; std::unique_ptr _readPartialByteSequence; std::unique_ptr _writePartialByteSequence; Microsoft::Console::VirtualTerminal::TerminalInput _termInput; // 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>& 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>& inRecords, _Out_ size_t& eventsWritten, _Out_ bool& setWaitEvent); bool _CanCoalesce(const KeyEvent& a, const KeyEvent& b) const noexcept; bool _CoalesceMouseMovedEvents(_Inout_ std::deque>& inEvents); bool _CoalesceRepeatedKeyPressEvents(_Inout_ std::deque>& inEvents); void _HandleConsoleSuspensionEvents(_Inout_ std::deque>& inEvents); void _HandleTerminalInputCallback(_In_ std::deque>& inEvents); #ifdef UNIT_TESTING friend class InputBufferTests; #endif };