VT100debugport console no longer requires you to disable size detect in vt100.ini
// Server.cpp
//
// Copyright (c) 2010 Accenture. All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Accenture - Initial contribution
//
#include "Misc.h"
#include "stdafx.h"
#include "console_host.h"
#include "Server.h"
#include "ConsoleWindow.h"
#include "RemoteConsole.h"
const int KMajorVersion = 1;
const int KServerInitParam = ID_RC_CLOSE - 1;
static CServer* sServer = NULL;
LPCTSTR KServerWindowClassName = TEXT("ServerWindowClass");
LPCTSTR KServerConsoleName = TEXT("Server Console");
LPCTSTR KServerSocketName = TEXT("Server Socket");
class TCreateConsoleWindowPacket
{
public:
void Validate() const;
public:
int iMajorVersion;
int iMinorVersion;
int iWidth;
int iHeight;
int iTitleLength;
};
void TCreateConsoleWindowPacket::Validate() const
{
if (iMajorVersion > KMajorVersion)
{
throw KExceptionInvalidClientVersion;
}
}
CServer* CServer::New(HINSTANCE aAppHandle)
{
std::auto_ptr<CServer> self(new(EThrow) CServer(aAppHandle));
self->Construct();
return self.release();
}
CServer::~CServer()
{
delete iSocket;
delete iConsole;
}
void CServer::HandleException(TException aException)
{
switch (aException)
{
case KExceptionNoMemory:
iConsole->Write(TEXT("Out of memory\r\n"));
break;
case KExceptionWindowConstructFailed:
iConsole->Write(TEXT("Failed to construct new window\r\n"));
break;
case KExceptionConsoleWindowConstructFailed:
iConsole->Write(TEXT("Failed to construct new console window\r\n"));
break;
case KExceptionSocketConstructFailed:
iConsole->Write(TEXT("Failed to construct new socket\r\n"));
break;
case KExceptionSocketBindFailed:
iConsole->Write(TEXT("Failed to bind server socket. Is something else already listening on that port?\r\n"));
break;
case KExceptionSocketListenFailed:
iConsole->Write(TEXT("Failed to listen on server socket\r\n"));
break;
case KExceptionSocketSelectFailed:
iConsole->Write(TEXT("Failed to asynchronously wait on socket\r\n"));
break;
case KExceptionSocketAcceptFailed:
iConsole->Write(TEXT("Failed to accept to client connection\r\n"));
break;
case KExceptionSocketReadFailed:
iConsole->Write(TEXT("Failed to read from socket\r\n"));
break;
case KExceptionInvalidClientVersion:
iConsole->Write(TEXT("Invalid client version\r\n"));
break;
case KExceptionFailedToWritePrefsFile:
iConsole->Write(TEXT("Failed to write preferences file\r\n"));
break;
default:
iConsole->Write(TEXT("Unknown error\r\n"));
break;
}
}
TPreferences& CServer::Preferences()
{
return iPreferences;
}
const TPreferences& CServer::Preferences() const
{
return iPreferences;
}
CServer::CServer(HINSTANCE aAppHandle) : iAppHandle(aAppHandle), iSocket(NULL), iConsole(NULL), iPort(0)
{
sServer = this;
}
void CServer::Construct()
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)CWindow::HandleMessage;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = iAppHandle;
wcex.hIcon = LoadIcon(iAppHandle, (LPCTSTR)IDI_CONSOLE_HOST);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = NULL;
wcex.lpszMenuName = (LPCTSTR)ID_SERVER_MENU;
wcex.lpszClassName = KServerWindowClassName;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
if (RegisterClassEx(&wcex) == 0)
{
throw KExceptionWindowClassRegistrationFailed;
}
iConsole = CConsoleWindow::New(iAppHandle, KServerWindowClassName, TEXT("Remote Console Server"), CW_USEDEFAULT, CW_USEDEFAULT, 40, 20, 20, this, NULL, TRUE);
iConsole->SetName(KServerConsoleName);
try
{
iPreferences.Read();
}
catch (...)
{
iConsole->Write(TEXT("Unable to read preferences"));
}
iSocket = CServerSocket::New(*iConsole);
iSocket->SetName(KServerSocketName);
PostMessage(iConsole->Handle(), WM_COMMAND, KServerInitParam, 0);
}
void CServer::Listen()
{
if (iPort != iPreferences.ServerPort())
{
delete iSocket;
iSocket = CServerSocket::New(*iConsole);
iSocket->SetName(KServerSocketName);
iSocket->Listen(iPreferences.ServerPort(), 5, *this);
iConsole->WriteFormat(TEXT("Listening on port %d\r\n"), iPreferences.ServerPort());
iPort = iPreferences.ServerPort();
}
}
void CServer::HandleNewClient(CClientSocket& aClientSocket)
{
CSocketCommandReader* commandReader = CSocketCommandReader::New(aClientSocket, *this);
commandReader->ReadCommand();
}
void CServer::HandleSocketClosure(CSocket& aSocket)
{
ASSERT(&aSocket == iSocket);
PostQuitMessage(0);
}
void CServer::HandleSocketCommand(TPacketHeader::TPacketType aCommand, const char* aPacket, int aPacketLength, CSocketCommandReader& aReader)
{
switch (aCommand)
{
case TPacketHeader::ECommandCreateConsoleWindow:
{
iConsole->Write(TEXT("Creating new console window...\r\n"));
const TCreateConsoleWindowPacket* createConsoleWindowPacket = new((char*)aPacket) TCreateConsoleWindowPacket;
LPTSTR title = (TCHAR*)((char*)aPacket + sizeof(TCreateConsoleWindowPacket));
try
{
createConsoleWindowPacket->Validate();
CRemoteConsole* remoteConsole = CRemoteConsole::New(iAppHandle, aReader, title, createConsoleWindowPacket->iWidth, createConsoleWindowPacket->iHeight, iPreferences);
int consoleId = remoteConsole->Id();
iConsole->WriteFormat(TEXT("Created window \"%s\" (%d)...\r\n"), title, consoleId);
aReader.SendResponse((char*)&consoleId, sizeof(int));
}
catch (TException aException)
{
int err = -2; // KErrGeneral.
if (aException == KExceptionInvalidClientVersion)
{
err = -21; // KErrAccessDenied.
}
aReader.SendResponse((char*)&err, sizeof(int));
delete &aReader;
throw aException;
}
catch (...)
{
delete &aReader;
throw KExceptionUnknown;
}
break;
}
case TPacketHeader::ECommandAttachKeyEventSocket:
{
iConsole->Write(TEXT("Attaching key event socket...\r\n"));
int* consoleId = new((char*)aPacket) int;
CRemoteConsole* remoteConsole = CRemoteConsole::Instance(*consoleId);
if (remoteConsole)
{
remoteConsole->AttachKeyEventSocket(aReader.ReleaseSocket());
iConsole->WriteFormat(TEXT("Attached key event socket to window %d...\r\n"), *consoleId);
}
delete &aReader;
break;
}
default:
{
iConsole->WriteFormat(TEXT("Invalid server socket command: %d\r\n"), aCommand);
delete &aReader;
break;
}
}
}
void CServer::HandleSocketClosure(CSocketCommandReader& aReader)
{
delete &aReader;
}
void CServer::HandleWindowClosure(CWindow& aWindow)
{
ASSERT(&aWindow == iConsole);
PostQuitMessage(0);
}
LRESULT CALLBACK PrefsCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
TCHAR string[128];
swprintf(string, TEXT("%u"), sServer->Preferences().ServerPort());
SetDlgItemText(hDlg, ID_EDIT_PORT, string);
swprintf(string, TEXT("%u"), sServer->Preferences().DefaultWindowWidth());
SetDlgItemText(hDlg, ID_EDIT_WIN_WIDTH, string);
swprintf(string, TEXT("%u"), sServer->Preferences().DefaultWindowHeight());
SetDlgItemText(hDlg, ID_EDIT_WIN_HEIGHT, string);
swprintf(string, TEXT("%u"), sServer->Preferences().DefaultWindowPosX());
SetDlgItemText(hDlg, ID_EDIT_WIN_POS_X, string);
swprintf(string, TEXT("%u"), sServer->Preferences().DefaultWindowPosY());
SetDlgItemText(hDlg, ID_EDIT_WIN_POS_Y, string);
EnableWindow(GetDlgItem(hDlg, ID_EDIT_WIN_POS_X), !sServer->Preferences().SystemPositionedWindows());
EnableWindow(GetDlgItem(hDlg, ID_EDIT_WIN_POS_Y), !sServer->Preferences().SystemPositionedWindows());
CheckDlgButton(hDlg, ID_CHECK_WIN_POS, sServer->Preferences().SystemPositionedWindows());
swprintf(string, TEXT("%u"), sServer->Preferences().NumOverflowLines());
SetDlgItemText(hDlg, ID_OVERFLOW_LINES, string);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
{
TCHAR string[128];
GetDlgItemText(hDlg, ID_EDIT_PORT, string, 128);
unsigned int val;
swscanf(string, TEXT("%u"), &val);
sServer->Preferences().SetServerPort((unsigned short)val);
GetDlgItemText(hDlg, ID_EDIT_WIN_WIDTH, string, 128);
swscanf(string, TEXT("%u"), &val);
sServer->Preferences().SetDefaultWindowWidth(val);
GetDlgItemText(hDlg, ID_EDIT_WIN_HEIGHT, string, 128);
swscanf(string, TEXT("%u"), &val);
sServer->Preferences().SetDefaultWindowHeight(val);
GetDlgItemText(hDlg, ID_EDIT_WIN_POS_X, string, 128);
swscanf(string, TEXT("%u"), &val);
sServer->Preferences().SetDefaultWindowPosX(val);
GetDlgItemText(hDlg, ID_EDIT_WIN_POS_Y, string, 128);
swscanf(string, TEXT("%u"), &val);
sServer->Preferences().SetDefaultWindowPosY(val);
GetDlgItemText(hDlg, ID_OVERFLOW_LINES, string, 128);
swscanf(string, TEXT("%u"), &val);
sServer->Preferences().SetNumOverflowLines(val);
sServer->Preferences().SetSystemPositionedWindows((IsDlgButtonChecked(hDlg, ID_CHECK_WIN_POS) == BST_CHECKED) ? TRUE : FALSE);
sServer->Preferences().Write();
sServer->Listen();
} // Deliberate fall through.
case IDCANCEL:
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
case ID_CHECK_WIN_POS:
{
int isChecked = IsDlgButtonChecked(hDlg, ID_CHECK_WIN_POS);
EnableWindow(GetDlgItem(hDlg, ID_EDIT_WIN_POS_X), !isChecked);
EnableWindow(GetDlgItem(hDlg, ID_EDIT_WIN_POS_Y), !isChecked);
break;
}
}
break;
}
return FALSE;
}
LRESULT CServer::HandleWindowCommand(UINT aMessage, WPARAM aWParam, LPARAM aLParam)
{
int wmId = LOWORD(aWParam);
int wmEvent = HIWORD(aWParam);
switch (wmId)
{
case KServerInitParam:
Listen();
break;
case ID_PREFS:
DialogBox(iAppHandle, (LPCTSTR)IDD_PREFS_DIALOG, iConsole->Handle(), (DLGPROC)PrefsCallback);
break;
default:
return DefWindowProc(iConsole->Handle(), aMessage, aWParam, aLParam);
}
return 0;
}