aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/3rdparty/winpty/src/agent/Win32ConsoleBuffer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/3rdparty/winpty/src/agent/Win32ConsoleBuffer.cc')
-rw-r--r--src/libs/3rdparty/winpty/src/agent/Win32ConsoleBuffer.cc193
1 files changed, 193 insertions, 0 deletions
diff --git a/src/libs/3rdparty/winpty/src/agent/Win32ConsoleBuffer.cc b/src/libs/3rdparty/winpty/src/agent/Win32ConsoleBuffer.cc
new file mode 100644
index 0000000000..ed93f4081f
--- /dev/null
+++ b/src/libs/3rdparty/winpty/src/agent/Win32ConsoleBuffer.cc
@@ -0,0 +1,193 @@
+// Copyright (c) 2011-2016 Ryan Prichard
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include "Win32ConsoleBuffer.h"
+
+#include <windows.h>
+
+#include "../shared/DebugClient.h"
+#include "../shared/StringBuilder.h"
+#include "../shared/WinptyAssert.h"
+
+std::unique_ptr<Win32ConsoleBuffer> Win32ConsoleBuffer::openStdout() {
+ return std::unique_ptr<Win32ConsoleBuffer>(
+ new Win32ConsoleBuffer(GetStdHandle(STD_OUTPUT_HANDLE), false));
+}
+
+std::unique_ptr<Win32ConsoleBuffer> Win32ConsoleBuffer::openConout() {
+ const HANDLE conout = CreateFileW(L"CONOUT$",
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, 0, NULL);
+ ASSERT(conout != INVALID_HANDLE_VALUE);
+ return std::unique_ptr<Win32ConsoleBuffer>(
+ new Win32ConsoleBuffer(conout, true));
+}
+
+std::unique_ptr<Win32ConsoleBuffer> Win32ConsoleBuffer::createErrorBuffer() {
+ SECURITY_ATTRIBUTES sa = {};
+ sa.nLength = sizeof(sa);
+ sa.bInheritHandle = TRUE;
+ const HANDLE conout =
+ CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ &sa,
+ CONSOLE_TEXTMODE_BUFFER,
+ nullptr);
+ ASSERT(conout != INVALID_HANDLE_VALUE);
+ return std::unique_ptr<Win32ConsoleBuffer>(
+ new Win32ConsoleBuffer(conout, true));
+}
+
+HANDLE Win32ConsoleBuffer::conout() {
+ return m_conout;
+}
+
+void Win32ConsoleBuffer::clearLines(
+ int row,
+ int count,
+ const ConsoleScreenBufferInfo &info) {
+ // TODO: error handling
+ const int width = info.bufferSize().X;
+ DWORD actual = 0;
+ if (!FillConsoleOutputCharacterW(
+ m_conout, L' ', width * count, Coord(0, row),
+ &actual) || static_cast<int>(actual) != width * count) {
+ trace("FillConsoleOutputCharacterW failed");
+ }
+ if (!FillConsoleOutputAttribute(
+ m_conout, kDefaultAttributes, width * count, Coord(0, row),
+ &actual) || static_cast<int>(actual) != width * count) {
+ trace("FillConsoleOutputAttribute failed");
+ }
+}
+
+void Win32ConsoleBuffer::clearAllLines(const ConsoleScreenBufferInfo &info) {
+ clearLines(0, info.bufferSize().Y, info);
+}
+
+ConsoleScreenBufferInfo Win32ConsoleBuffer::bufferInfo() {
+ // TODO: error handling
+ ConsoleScreenBufferInfo info;
+ if (!GetConsoleScreenBufferInfo(m_conout, &info)) {
+ trace("GetConsoleScreenBufferInfo failed");
+ }
+ return info;
+}
+
+Coord Win32ConsoleBuffer::bufferSize() {
+ return bufferInfo().bufferSize();
+}
+
+SmallRect Win32ConsoleBuffer::windowRect() {
+ return bufferInfo().windowRect();
+}
+
+bool Win32ConsoleBuffer::resizeBufferRange(const Coord &initialSize,
+ Coord &finalSize) {
+ if (SetConsoleScreenBufferSize(m_conout, initialSize)) {
+ finalSize = initialSize;
+ return true;
+ }
+ // The font might be too small to accommodate a very narrow console window.
+ // In that case, rather than simply give up, it's better to try wider
+ // buffer sizes until the call succeeds.
+ Coord size = initialSize;
+ while (size.X < 20) {
+ size.X++;
+ if (SetConsoleScreenBufferSize(m_conout, size)) {
+ finalSize = size;
+ trace("SetConsoleScreenBufferSize: initial size (%d,%d) failed, "
+ "but wider size (%d,%d) succeeded",
+ initialSize.X, initialSize.Y,
+ finalSize.X, finalSize.Y);
+ return true;
+ }
+ }
+ trace("SetConsoleScreenBufferSize failed: "
+ "tried (%d,%d) through (%d,%d)",
+ initialSize.X, initialSize.Y,
+ size.X, size.Y);
+ return false;
+}
+
+void Win32ConsoleBuffer::resizeBuffer(const Coord &size) {
+ // TODO: error handling
+ if (!SetConsoleScreenBufferSize(m_conout, size)) {
+ trace("SetConsoleScreenBufferSize failed: size=(%d,%d)",
+ size.X, size.Y);
+ }
+}
+
+void Win32ConsoleBuffer::moveWindow(const SmallRect &rect) {
+ // TODO: error handling
+ if (!SetConsoleWindowInfo(m_conout, TRUE, &rect)) {
+ trace("SetConsoleWindowInfo failed");
+ }
+}
+
+Coord Win32ConsoleBuffer::cursorPosition() {
+ return bufferInfo().dwCursorPosition;
+}
+
+void Win32ConsoleBuffer::setCursorPosition(const Coord &coord) {
+ // TODO: error handling
+ if (!SetConsoleCursorPosition(m_conout, coord)) {
+ trace("SetConsoleCursorPosition failed");
+ }
+}
+
+void Win32ConsoleBuffer::read(const SmallRect &rect, CHAR_INFO *data) {
+ // TODO: error handling
+ SmallRect tmp(rect);
+ if (!ReadConsoleOutputW(m_conout, data, rect.size(), Coord(), &tmp) &&
+ isTracingEnabled()) {
+ StringBuilder sb(256);
+ auto outStruct = [&](const SMALL_RECT &sr) {
+ sb << "{L=" << sr.Left << ",T=" << sr.Top
+ << ",R=" << sr.Right << ",B=" << sr.Bottom << '}';
+ };
+ sb << "Win32ConsoleBuffer::read: ReadConsoleOutput failed: readRegion=";
+ outStruct(rect);
+ CONSOLE_SCREEN_BUFFER_INFO info = {};
+ if (GetConsoleScreenBufferInfo(m_conout, &info)) {
+ sb << ", dwSize=(" << info.dwSize.X << ',' << info.dwSize.Y
+ << "), srWindow=";
+ outStruct(info.srWindow);
+ } else {
+ sb << ", GetConsoleScreenBufferInfo also failed";
+ }
+ trace("%s", sb.c_str());
+ }
+}
+
+void Win32ConsoleBuffer::write(const SmallRect &rect, const CHAR_INFO *data) {
+ // TODO: error handling
+ SmallRect tmp(rect);
+ if (!WriteConsoleOutputW(m_conout, data, rect.size(), Coord(), &tmp)) {
+ trace("WriteConsoleOutput failed");
+ }
+}
+
+void Win32ConsoleBuffer::setTextAttribute(WORD attributes) {
+ if (!SetConsoleTextAttribute(m_conout, attributes)) {
+ trace("SetConsoleTextAttribute failed");
+ }
+}