barrier/lib/arch/CArchConsoleWindows.cpp

117 lines
2.8 KiB
C++

/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2002 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "CArchConsoleWindows.h"
#include "IArchMultithread.h"
#include "CArch.h"
#include <cstdio>
//
// CArchConsoleWindows
//
CArchThread CArchConsoleWindows::s_thread = 0;
CArchConsoleWindows::CArchConsoleWindows() :
m_output(NULL)
{
s_thread = ARCH->newCurrentThread();
m_mutex = ARCH->newMutex();
// dummy write to stderr to create locks in stdio from the main
// thread. if we open the console from another thread then we
// can deadlock in stdio when trying to write from a 3rd thread.
// writes to stderr without a console don't go anywhere so the
// user won't notice this.
fprintf(stderr, "\n");
}
CArchConsoleWindows::~CArchConsoleWindows()
{
ARCH->closeMutex(m_mutex);
ARCH->closeThread(s_thread);
}
void
CArchConsoleWindows::openConsole(const char* title)
{
ARCH->lockMutex(m_mutex);
if (m_output == NULL) {
if (AllocConsole()) {
// get console output handle
m_output = GetStdHandle(STD_ERROR_HANDLE);
// set console title
if (title != NULL) {
SetConsoleTitle(title);
}
// prep console. windows 95 and its ilk have braindead
// consoles that can't even resize independently of the
// buffer size. use a 25 line buffer for those systems.
OSVERSIONINFO osInfo;
COORD size = { 80, 1000 };
osInfo.dwOSVersionInfoSize = sizeof(osInfo);
if (GetVersionEx(&osInfo) &&
osInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
size.Y = 25;
SetConsoleScreenBufferSize(m_output, size);
SetConsoleTextAttribute(m_output,
FOREGROUND_RED |
FOREGROUND_GREEN |
FOREGROUND_BLUE);
// catch console signals
SetConsoleCtrlHandler(&CArchConsoleWindows::signalHandler, TRUE);
// reopen stderr to point at console
freopen("con", "w", stderr);
}
}
ARCH->unlockMutex(m_mutex);
}
void
CArchConsoleWindows::closeConsole()
{
ARCH->lockMutex(m_mutex);
if (m_output != NULL) {
if (FreeConsole()) {
m_output = NULL;
}
}
ARCH->unlockMutex(m_mutex);
}
void
CArchConsoleWindows::writeConsole(const char* str)
{
fprintf(stderr, "%s", str);
}
const char*
CArchConsoleWindows::getNewlineForConsole()
{
return "\r\n";
}
BOOL WINAPI
CArchConsoleWindows::signalHandler(DWORD)
{
// terminate app and skip remaining handlers
ARCH->interrupt();
return TRUE;
}