diff -r 000000000000 -r 7f656887cf89 plugins/consoles/consoleproxy/src/server.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/consoles/consoleproxy/src/server.cpp Wed Jun 23 15:52:26 2010 +0100 @@ -0,0 +1,456 @@ +// server.cpp +// +// Copyright (c) 2009 - 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 +#include "server.h" + +_LIT(KPronxyConsolePanic, "proxyconsole"); + +void Panic(TConsoleProxyPanic aReason) + { + User::Panic(KPronxyConsolePanic, aReason); + } + + +void ServerThreadL(TServerParams* aParams) + { + CActiveScheduler* as = new(ELeave)CActiveScheduler; + CleanupStack::PushL(as); + CActiveScheduler::Install(as); + + CConsoleProxyServer* server = (aParams->iServerNewL)(aParams->iServerParams); + CleanupStack::PushL(server); + + aParams->iServer = server->Server(); + RThread::Rendezvous(KErrNone); + + CActiveScheduler::Start(); + + CleanupStack::PopAndDestroy(2, as); + } + + +TInt ServerThreadFunction(TAny* aArgs) + { + __UHEAP_MARK; + User::SetCritical(User::ENotCritical); + + TServerParams* params = (TServerParams*)aArgs; + + CTrapCleanup* cleanup = CTrapCleanup::New(); + if (!cleanup) + { + return KErrNoMemory; + } + + TRAPD(err, ServerThreadL(params)); + + delete cleanup; + __UHEAP_MARKEND; + return err; + } + +//______________________________________________________________________________ +// CConsoleProxyServer +CConsoleProxyServer* CConsoleProxyServer::NewL(TAny* aParams) + { + TConsoleProxyServerNewLParams* params = (TConsoleProxyServerNewLParams*)aParams; + return NewL(params->iName, params->iAoPriority, params->iConsoleCreate); + } + +EXPORT_C CConsoleProxyServer* CConsoleProxyServer::NewL(const TDesC& aName, TInt aAoPriority, TConsoleCreateFunction aConsoleCreate) + { + CConsoleProxyServer* self = new(ELeave)CConsoleProxyServer(aConsoleCreate, aAoPriority); + CleanupStack::PushL(self); + self->ConstructL(aName); + CleanupStack::Pop(self); + return self; + } + +EXPORT_C void CConsoleProxyServer::ConstructL(const TDesC& aName) + { + StartL(aName); + iShutdownTimer = CShutdownTimer::NewL(*this); + iShutdownTimer->Start(); + } + +EXPORT_C CConsoleProxyServer::CConsoleProxyServer(TConsoleCreateFunction aConsoleCreate, TInt aAoPriority) + : CServer2(aAoPriority, CServer2::ESharableSessions) + , iConsoleCreate(aConsoleCreate) + { + } + +EXPORT_C CConsoleProxyServer::~CConsoleProxyServer() + { + delete iShutdownTimer; + iShutdownTimer = NULL; // Can be referenced by session destructors which run after this, as part of ~CServer2, which will call ~CConsoleProxySession which can call DropSession... + } + +EXPORT_C void CConsoleProxyServer::ShutdownTimerExpired() + { + CActiveScheduler::Stop(); + } + +EXPORT_C CSession2* CConsoleProxyServer::NewSessionL(const TVersion&,const RMessage2&) const + { + return new(ELeave)CConsoleProxySession(iConsoleCreate); + } + +void CConsoleProxyServer::AddSession() + { + iShutdownTimer->Cancel(); + ++iSessionCount; + } + +void CConsoleProxyServer::DropSession() + { + --iSessionCount; + if ((iSessionCount==0) && iShutdownTimer && (!iShutdownTimer->IsActive())) + { + iShutdownTimer->Start(); + } + } + +//______________________________________________________________________________ +// CConsoleProxySession +EXPORT_C CConsoleProxySession::CConsoleProxySession(TConsoleCreateFunction aConsoleCreate) + : iConsoleCreate(aConsoleCreate) + { + } + +EXPORT_C CConsoleProxySession::CConsoleProxySession(MProxiedConsole* aConsole) + : iConsole(aConsole) + { + iConsole->Open(); + } + +EXPORT_C CConsoleProxySession::~CConsoleProxySession() + { + Server()->DropSession(); + if (!iReadMessage.IsNull()) + { + iReadMessage.Complete(KErrDisconnected); + if (iConsole) iConsole->ReadCancel(); + } + if (iConsole) iConsole->Close(); + } + +EXPORT_C void CConsoleProxySession::CreateL() + { + Server()->AddSession(); + } + +EXPORT_C void CConsoleProxySession::ServiceL(const RMessage2& aMessage) + { + if (!iConsole && (aMessage.Function() != RConsoleProxy::ECreate)) + { + User::Leave(KErrNotReady); + } + RBuf buf; + CleanupClosePushL(buf); + TBool complete = ETrue; + switch (aMessage.Function()) + { + case RConsoleProxy::ECreate: + CreateL(aMessage); + break; + case RConsoleProxy::ERead: + if (!iReadMessage.IsNull()) User::Leave(KErrAlreadyExists); + iReadType = EReadBasic; + iReadMessage = aMessage; + iConsole->Read(*this); + complete = EFalse; + break; + case RConsoleProxy::EReadKey: + if (!iReadMessage.IsNull()) User::Leave(KErrAlreadyExists); + iReadType = EReadKeys; + iReadMessage = aMessage; + iConsole->Read(*this); + complete = EFalse; + break; + case RConsoleProxy::EReadCancel: + if (!iReadMessage.IsNull()) + { + iReadMessage.Complete(KErrCancel); + iConsole->ReadCancel(); + } + break; + case RConsoleProxy::EWrite: + buf.CreateL(aMessage.GetDesLengthL(0)); + aMessage.ReadL(0, buf); + iConsole->Console()->Write(buf); + break; + case RConsoleProxy::EGetCursorPos: + { + TPckgBuf pos; + pos() = iConsole->Console()->CursorPos(); + aMessage.WriteL(0, pos); + break; + } + case RConsoleProxy::ESetCursorPosAbs: + { + TPoint pos(aMessage.Int0(), aMessage.Int1()); + iConsole->Console()->SetCursorPosAbs(pos); + break; + } + case RConsoleProxy::ESetCursorPosRel: + { + TPoint pos(aMessage.Int0(), aMessage.Int1()); + iConsole->Console()->SetCursorPosRel(pos); + break; + } + case RConsoleProxy::ESetCursorHeight: + iConsole->Console()->SetCursorHeight(aMessage.Int0()); + break; + case RConsoleProxy::ESetTitle: + buf.CreateL(aMessage.GetDesLengthL(0)); + aMessage.ReadL(0, buf); + iConsole->Console()->SetTitle(buf); + break; + case RConsoleProxy::EClearScreen: + iConsole->Console()->ClearScreen(); + break; + case RConsoleProxy::EClearToEndOfLine: + iConsole->Console()->ClearToEndOfLine(); + break; + case RConsoleProxy::EGetScreenSize: + { + TPckgBuf size; + if (aMessage.GetDesLengthL(0)!=size.Length()) User::Leave(KErrArgument); + size() = iConsole->Console()->ScreenSize(); + aMessage.WriteL(0, size); + break; + } + case RConsoleProxy::EGetKeyCode: + { + TPckg kc(iKeyCode); + if (aMessage.GetDesLengthL(0)!=kc.Length()) User::Leave(KErrArgument); + aMessage.WriteL(0, kc); + break; + } + case RConsoleProxy::EGetKeyModifiers: + { + TPckg mod(iKeyModifiers); + if (aMessage.GetDesLengthL(0)!=mod.Length()) User::Leave(KErrArgument); + aMessage.WriteL(0, mod); + break; + } + case RConsoleProxy::ESetAttributes: + { + if (!iConsole) User::Leave(KErrNotReady); + ConsoleAttributes::TAttributes attributes((TUint)aMessage.Int0(), (ConsoleAttributes::TColor)aMessage.Int1(), (ConsoleAttributes::TColor)aMessage.Int2()); + TInt err = ConsoleAttributes::Set(iConsole->Console(), attributes); + aMessage.Complete(err); + complete = EFalse; + break; + } + case RConsoleProxy::EIsConstructed: + { + if (aMessage.GetDesLengthL(0)!=sizeof(TBool)) User::Leave(KErrArgument); + if (!iConsole) User::Leave(KErrNotReady); + if (!LazyConsole::IsLazy(iConsole->Console())) User::Leave(KErrExtensionNotSupported); + TPckgBuf constructed = LazyConsole::IsConstructed(iConsole->Console()); + aMessage.WriteL(0, constructed); + complete = ETrue; + break; + } + default: + aMessage.Complete(KErrNotSupported); + } + CleanupStack::PopAndDestroy(&buf); + if (complete) + { + aMessage.Complete(KErrNone); + } + } + +EXPORT_C void CConsoleProxySession::ReadComplete(TInt aStatus) + { + iKeyCode = iConsole->Console()->KeyCode(); + iKeyModifiers = iConsole->Console()->KeyModifiers(); + if (!iReadMessage.IsNull()) + { + TInt err = aStatus; + if (iReadType == EReadKeys) + { + if (err == KErrNone) + { + err = iReadMessage.Write(0, TPckg(iKeyCode)); + } + if (err == KErrNone) + { + err = iReadMessage.Write(1, TPckg(iKeyModifiers)); + } + } + + iReadMessage.Complete(err); + } + } + +EXPORT_C void CConsoleProxySession::DoCreateL(const TDesC& aTitle, const TSize& aSize) + { + __ASSERT_ALWAYS(!iConsole, Panic(EConsoleAlreadyCreated)); + MProxiedConsole* cons = InstantiateConsoleL(); + __ASSERT_ALWAYS(cons, Panic(ENoConsoleInstatiated)); + CleanupClosePushL(*cons); + TName procName = RProcess().Name(); // econseik sets the process name to the console title... + TInt err = cons->Console()->Create(aTitle, aSize); + User::RenameProcess(procName.Left(procName.Locate('['))); // ...so restore it just in case + User::LeaveIfError(err); + + ConsoleCreatedL(cons); + + iConsole = cons; + CleanupStack::Pop(cons); + } + +EXPORT_C void CConsoleProxySession::ConsoleCreatedL(MProxiedConsole*) + { + } + +void CConsoleProxySession::CreateL(const RMessage2& aMessage) + { + if (iConsole) User::Leave(KErrAlreadyExists); + RBuf title; + title.CreateL(aMessage.GetDesLengthL(0)); + CleanupClosePushL(title); + aMessage.ReadL(0, title); + + TSize size(aMessage.Int1(), aMessage.Int2()); + + DoCreateL(title, size); + + CleanupStack::PopAndDestroy(&title); + } + +EXPORT_C MProxiedConsole* CConsoleProxySession::InstantiateConsoleL() + { + return CConsoleWrapper::NewL(iConsoleCreate); + } + + +//______________________________________________________________________________ +// MProxiedConsole +EXPORT_C MProxiedConsole* MProxiedConsole::DefaultL(CConsoleBase* aConsole) + { + return CConsoleWrapper::NewL(aConsole); + } +//______________________________________________________________________________ +// CConsoleWrapper +CConsoleWrapper* CConsoleWrapper::NewL(TConsoleCreateFunction aConsoleCreate) + { + CConsoleWrapper* self = new(ELeave)CConsoleWrapper; + CleanupStack::PushL(self); + self->ConstructL(aConsoleCreate); + CleanupStack::Pop(self); + return self; + } + +CConsoleWrapper* CConsoleWrapper::NewL(CConsoleBase* aConsole) + { + CConsoleWrapper* self = new(ELeave)CConsoleWrapper; + self->iConsole = aConsole; + return self; + } + +CConsoleWrapper::~CConsoleWrapper() + { + Cancel(); + delete iConsole; + } + +void CConsoleWrapper::Open() + { + ++iRefCount; + } + +void CConsoleWrapper::Close() + { + --iRefCount; + if (!iRefCount) + { + delete this; + } + } + +CConsoleBase* CConsoleWrapper::Console() + { + return iConsole; + } + +void CConsoleWrapper::Read(CConsoleProxySession& aSession) + { + if (!IsActive()) + { + iReader = &aSession; + iConsole->Read(iStatus); + SetActive(); + } + } + +void CConsoleWrapper::ReadCancel() + { + Cancel(); + iReader = NULL; + } + +void CConsoleWrapper::RunL() + { + iReader->ReadComplete(iStatus.Int()); + } + +void CConsoleWrapper::DoCancel() + { + iConsole->ReadCancel(); + } + +void CConsoleWrapper::ConstructL(TConsoleCreateFunction aConsoleCreate) + { + iConsole = aConsoleCreate(); + User::LeaveIfNull(iConsole); + } + +CConsoleWrapper::CConsoleWrapper() + : CActive(CActive::EPriorityStandard) + , iRefCount(1) + { + CActiveScheduler::Add(this); + } + + +//______________________________________________________________________________ +// CShutdownTimer +CShutdownTimer* CShutdownTimer::NewL(CConsoleProxyServer& aServer) + { + CShutdownTimer* self = new(ELeave)CShutdownTimer(aServer); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +CShutdownTimer::CShutdownTimer(CConsoleProxyServer& aServer) + : CTimer(CActive::EPriorityLow), iServer(aServer) + { + CActiveScheduler::Add(this); + } + +void CShutdownTimer::Start() + { + After(KServerShutdownTimer); + } + +void CShutdownTimer::RunL() + { + iServer.ShutdownTimerExpired(); + } +