2011-11-17 11:00:02 +00:00
|
|
|
#include "Win32Console.h"
|
2012-03-14 06:27:21 +00:00
|
|
|
#include "AgentAssert.h"
|
2012-03-15 08:59:12 +00:00
|
|
|
#include "../Shared/DebugClient.h"
|
2011-11-17 11:00:02 +00:00
|
|
|
#include <windows.h>
|
|
|
|
|
2012-03-13 07:16:51 +00:00
|
|
|
Win32Console::Win32Console()
|
2011-11-17 11:00:02 +00:00
|
|
|
{
|
|
|
|
m_conin = CreateFile(
|
|
|
|
L"CONIN$",
|
|
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
|
|
NULL, OPEN_EXISTING, 0, NULL);
|
|
|
|
m_conout = CreateFile(
|
|
|
|
L"CONOUT$",
|
|
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
|
|
NULL, OPEN_EXISTING, 0, NULL);
|
2012-03-14 06:27:21 +00:00
|
|
|
ASSERT(m_conin != NULL);
|
|
|
|
ASSERT(m_conout != NULL);
|
2011-11-17 11:00:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Win32Console::~Win32Console()
|
|
|
|
{
|
|
|
|
CloseHandle(m_conin);
|
|
|
|
CloseHandle(m_conout);
|
|
|
|
}
|
|
|
|
|
|
|
|
HANDLE Win32Console::conin()
|
|
|
|
{
|
|
|
|
return m_conin;
|
|
|
|
}
|
|
|
|
|
|
|
|
HANDLE Win32Console::conout()
|
|
|
|
{
|
|
|
|
return m_conout;
|
|
|
|
}
|
|
|
|
|
|
|
|
HWND Win32Console::hwnd()
|
|
|
|
{
|
|
|
|
return GetConsoleWindow();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Win32Console::postCloseMessage()
|
|
|
|
{
|
|
|
|
HWND h = hwnd();
|
|
|
|
if (h != NULL)
|
|
|
|
PostMessage(h, WM_CLOSE, 0, 0);
|
|
|
|
}
|
|
|
|
|
2012-03-13 07:16:51 +00:00
|
|
|
Coord Win32Console::bufferSize()
|
2011-11-17 11:00:02 +00:00
|
|
|
{
|
|
|
|
// TODO: error handling
|
2012-03-15 08:59:12 +00:00
|
|
|
CONSOLE_SCREEN_BUFFER_INFO info;
|
|
|
|
memset(&info, 0, sizeof(info));
|
|
|
|
if (!GetConsoleScreenBufferInfo(m_conout, &info)) {
|
|
|
|
Trace("GetConsoleScreenBufferInfo failed");
|
|
|
|
}
|
2012-03-13 07:16:51 +00:00
|
|
|
return info.dwSize;
|
2011-11-17 11:00:02 +00:00
|
|
|
}
|
|
|
|
|
2012-03-13 07:16:51 +00:00
|
|
|
SmallRect Win32Console::windowRect()
|
2011-11-17 11:00:02 +00:00
|
|
|
{
|
|
|
|
// TODO: error handling
|
2012-03-15 08:59:12 +00:00
|
|
|
CONSOLE_SCREEN_BUFFER_INFO info;
|
|
|
|
memset(&info, 0, sizeof(info));
|
|
|
|
if (!GetConsoleScreenBufferInfo(m_conout, &info)) {
|
|
|
|
Trace("GetConsoleScreenBufferInfo failed");
|
|
|
|
}
|
2012-03-13 07:16:51 +00:00
|
|
|
return info.srWindow;
|
2011-11-17 11:00:02 +00:00
|
|
|
}
|
|
|
|
|
2012-03-13 07:16:51 +00:00
|
|
|
void Win32Console::resizeBuffer(const Coord &size)
|
2011-11-17 11:00:02 +00:00
|
|
|
{
|
|
|
|
// TODO: error handling
|
2012-03-15 08:59:12 +00:00
|
|
|
if (!SetConsoleScreenBufferSize(m_conout, size)) {
|
|
|
|
Trace("SetConsoleScreenBufferSize failed");
|
|
|
|
}
|
2011-11-17 11:00:02 +00:00
|
|
|
}
|
|
|
|
|
2012-03-13 07:16:51 +00:00
|
|
|
void Win32Console::moveWindow(const SmallRect &rect)
|
2011-11-17 11:00:02 +00:00
|
|
|
{
|
|
|
|
// TODO: error handling
|
2012-03-15 08:59:12 +00:00
|
|
|
if (!SetConsoleWindowInfo(m_conout, TRUE, &rect)) {
|
|
|
|
Trace("SetConsoleWindowInfo failed");
|
|
|
|
}
|
2011-11-17 11:00:02 +00:00
|
|
|
}
|
|
|
|
|
2012-03-13 07:16:51 +00:00
|
|
|
void Win32Console::reposition(const Coord &newBufferSize,
|
|
|
|
const SmallRect &newWindowRect)
|
2011-11-17 11:00:02 +00:00
|
|
|
{
|
|
|
|
// Windows has one API for resizing the screen buffer and a different one
|
|
|
|
// for resizing the window. It seems that either API can fail if the
|
|
|
|
// window does not fit on the screen buffer.
|
|
|
|
|
2012-03-13 07:16:51 +00:00
|
|
|
const SmallRect origWindowRect(windowRect());
|
|
|
|
const SmallRect origBufferRect(Coord(), bufferSize());
|
2011-11-17 11:00:02 +00:00
|
|
|
|
2012-03-14 06:27:21 +00:00
|
|
|
ASSERT(!newBufferSize.isEmpty());
|
2012-03-13 07:16:51 +00:00
|
|
|
SmallRect bufferRect(Coord(), newBufferSize);
|
2012-03-14 06:27:21 +00:00
|
|
|
ASSERT(bufferRect.contains(newWindowRect));
|
2011-11-17 11:00:02 +00:00
|
|
|
|
2012-03-13 07:16:51 +00:00
|
|
|
SmallRect tempWindowRect = origWindowRect.intersected(bufferRect);
|
2011-11-17 11:00:02 +00:00
|
|
|
if (tempWindowRect.width() <= 0) {
|
2012-03-13 07:16:51 +00:00
|
|
|
tempWindowRect.setLeft(newBufferSize.X - 1);
|
2011-11-17 11:00:02 +00:00
|
|
|
tempWindowRect.setWidth(1);
|
|
|
|
}
|
|
|
|
if (tempWindowRect.height() <= 0) {
|
2012-03-13 07:16:51 +00:00
|
|
|
tempWindowRect.setTop(newBufferSize.Y - 1);
|
2011-11-17 11:00:02 +00:00
|
|
|
tempWindowRect.setHeight(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Alternatively, if we can immediately use the new window size,
|
|
|
|
// do that instead.
|
|
|
|
if (origBufferRect.contains(newWindowRect))
|
|
|
|
tempWindowRect = newWindowRect;
|
|
|
|
|
|
|
|
if (tempWindowRect != origWindowRect)
|
|
|
|
moveWindow(tempWindowRect);
|
|
|
|
resizeBuffer(newBufferSize);
|
|
|
|
if (newWindowRect != tempWindowRect)
|
|
|
|
moveWindow(newWindowRect);
|
|
|
|
}
|
|
|
|
|
2012-03-13 07:16:51 +00:00
|
|
|
Coord Win32Console::cursorPosition()
|
2011-11-17 11:00:02 +00:00
|
|
|
{
|
|
|
|
// TODO: error handling
|
2012-03-15 08:59:12 +00:00
|
|
|
CONSOLE_SCREEN_BUFFER_INFO info;
|
|
|
|
memset(&info, 0, sizeof(info));
|
|
|
|
if (!GetConsoleScreenBufferInfo(m_conout, &info)) {
|
|
|
|
Trace("GetConsoleScreenBufferInfo failed");
|
|
|
|
}
|
2012-03-13 07:16:51 +00:00
|
|
|
return info.dwCursorPosition;
|
2011-11-17 11:00:02 +00:00
|
|
|
}
|
|
|
|
|
2012-03-13 07:16:51 +00:00
|
|
|
void Win32Console::setCursorPosition(const Coord &coord)
|
2011-11-17 11:00:02 +00:00
|
|
|
{
|
|
|
|
// TODO: error handling
|
2012-03-15 08:59:12 +00:00
|
|
|
if (!SetConsoleCursorPosition(m_conout, coord)) {
|
|
|
|
Trace("SetConsoleCursorPosition failed");
|
|
|
|
}
|
2011-11-17 11:00:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Win32Console::writeInput(const INPUT_RECORD *ir, int count)
|
|
|
|
{
|
|
|
|
// TODO: error handling
|
2012-03-15 08:59:12 +00:00
|
|
|
DWORD dummy = 0;
|
|
|
|
if (!WriteConsoleInput(m_conin, ir, count, &dummy)) {
|
|
|
|
Trace("WriteConsoleInput failed");
|
|
|
|
}
|
2011-11-17 11:00:02 +00:00
|
|
|
}
|
|
|
|
|
2012-03-13 07:16:51 +00:00
|
|
|
void Win32Console::read(const SmallRect &rect, CHAR_INFO *data)
|
2011-11-17 11:00:02 +00:00
|
|
|
{
|
|
|
|
// TODO: error handling
|
2012-03-15 08:59:12 +00:00
|
|
|
SmallRect tmp(rect);
|
|
|
|
if (!ReadConsoleOutput(m_conout, data, rect.size(), Coord(), &tmp)) {
|
|
|
|
Trace("ReadConsoleOutput failed [x:%d,y:%d,w:%d,h:%d]",
|
|
|
|
rect.Left, rect.Top, rect.width(), rect.height());
|
|
|
|
}
|
2011-11-17 11:00:02 +00:00
|
|
|
}
|
|
|
|
|
2012-03-13 07:16:51 +00:00
|
|
|
void Win32Console::write(const SmallRect &rect, const CHAR_INFO *data)
|
2011-11-17 11:00:02 +00:00
|
|
|
{
|
|
|
|
// TODO: error handling
|
2012-03-15 08:59:12 +00:00
|
|
|
SmallRect tmp(rect);
|
|
|
|
if (!WriteConsoleOutput(m_conout, data, rect.size(), Coord(), &tmp)) {
|
|
|
|
Trace("WriteConsoleOutput failed");
|
|
|
|
}
|
2011-11-17 11:00:02 +00:00
|
|
|
}
|