Adjust path in .mk fshell files.
// persistentconsole.cpp
//
// Copyright (c) 2008 - 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 "persistentconsole.h"
#include <e32hashtab.h>
static void CleanupNullPointer(TAny* aPtrPtr)
{
*((TAny**)aPtrPtr) = NULL;
}
static void CleanupNullPointerPushL(TAny** aPtr)
{
CleanupStack::PushL(TCleanupItem(CleanupNullPointer, aPtr));
}
_LIT(KProxySuffix, "_proxy");
//______________________________________________________________________________
// CIoPersistentConsole
CIoPersistentConsole* CIoPersistentConsole::NewLC(const TDesC& aName, const TDesC& aTitle, CIoServer& aServer, const RMsg& aMessage)
{
CIoPersistentConsole* self = new(ELeave)CIoPersistentConsole(aServer);
CleanupClosePushL(*self);
self->ConstructL(aName, aTitle, aMessage);
return self;
}
TBool CIoPersistentConsole::CanConnectReaderL(const MIoReadEndPoint& aReader) const
{
// check that the candidate end point will not result in a circular connection of
// persistent consoles if it's connected to this one.
RHashSet<TInt> chained; // addresses of CIoPersistentConsole's in any chain
CleanupClosePushL(chained);
chained.InsertL((TInt)this);
const MIoReadEndPoint* nextReader = &aReader;
while (nextReader && nextReader->IoepIsType(RIoHandle::EPersistentConsole))
{
const CIoPersistentConsole* next = (const CIoPersistentConsole*)nextReader;
if (chained.Find((TInt)next))
{
CleanupStack::PopAndDestroy();
return EFalse;
}
chained.InsertL((TInt)next);
nextReader = next->TransientReader();
}
CleanupStack::PopAndDestroy();
return ETrue;
}
void CIoPersistentConsole::AttachTransientReaderL(MIoReadEndPoint& aReader, CIoSession* aDetachOnClose)
{
if (!CanConnectReaderL(aReader)) User::Leave(KErrCouldNotConnect);
if (iTransientReadEndPoint)
{
User::Leave(KErrInUse);
}
iTransientReadEndPoint = &aReader;
CleanupNullPointerPushL((TAny**)&iTransientReadEndPoint);
TInt fgProxyPos = ReaderProxyIndex(AttachedReader());
if (fgProxyPos != KErrNotFound)
{
iTransientReadEndPoint->IorepAttachL(*iReaderProxies[fgProxyPos], RIoEndPoint::EForeground);
}
TInt i = 0;
TRAPD(err,
for (i=0; i<iReaderProxies.Count(); ++i)
{
if (i != fgProxyPos)
{
iTransientReadEndPoint->IorepAttachL(*iReaderProxies[i], RIoEndPoint::EBackground);
}
}
);
if (err)
{
// deatch the readers the we successfully attached before failure
for (TInt j=0; j<i; ++j)
{
iTransientReadEndPoint->IorepDetach(*iReaderProxies[j]);
}
// also make sure that the foreground reader is deatched
if (fgProxyPos >= i)
{
iTransientReadEndPoint->IorepDetach(*iReaderProxies[fgProxyPos]);
}
User::Leave(err);
}
CleanupStack::Pop();
iReadEndPointDetachOnClose = aDetachOnClose;
// now foreward any outstanding read requests
for (TInt i=0; i<iReaderProxies.Count(); ++i)
{
iReaderProxies[i]->TransientReaderAttached(*iTransientReadEndPoint);
}
MIoReader* fg = AttachedReader();
if (fg)
{
fg->IorReaderChange(RIoReadHandle::EGainedForeground | RIoReadHandle::EConsoleSizeChanged);
}
}
void CIoPersistentConsole::DetachTransientReader()
{
if (!iTransientReadEndPoint)
{
return;
}
MIoReadEndPoint* detaching = iTransientReadEndPoint;
iTransientReadEndPoint = NULL;
TInt fgReaderPos = ReaderProxyIndex(AttachedReader());
for (TInt i=0; i<iReaderProxies.Count(); ++i)
{
if (i!=fgReaderPos)
{
detaching->IorepDetach(*iReaderProxies[i]);
}
}
if (fgReaderPos!=KErrNotFound)
{
detaching->IorepDetach(*iReaderProxies[fgReaderPos]);
}
iReadEndPointDetachOnClose = NULL;
SendReadDetachNotifications();
}
const MIoReadEndPoint* CIoPersistentConsole::TransientReader() const
{
return iTransientReadEndPoint;
}
TBool CIoPersistentConsole::CanConnectWriterL(const MIoWriteEndPoint& aWriter) const
{
// check that the candidate end point will not result in a circular connection of
// persistent consoles if it's connected to this one.
RHashSet<TInt> chained; // addresses of CIoPersistentConsole's in any chain
CleanupClosePushL(chained);
chained.InsertL((TInt)this);
const MIoWriteEndPoint* nextWriter = &aWriter;
while (nextWriter && nextWriter->IoepIsType(RIoHandle::EPersistentConsole))
{
const CIoPersistentConsole* next = (const CIoPersistentConsole*)nextWriter;
if (chained.Find((TInt)next))
{
CleanupStack::PopAndDestroy();
return EFalse;
}
chained.InsertL((TInt)next);
nextWriter = next->TransientWriter();
}
CleanupStack::PopAndDestroy();
return ETrue;
}
void CIoPersistentConsole::AttachTransientWriterL(MIoWriteEndPoint& aWriter, CIoSession* aDetachOnClose)
{
if (!CanConnectWriterL(aWriter)) User::Leave(KErrCouldNotConnect);
if (iTransientWriteEndPoint)
{
User::Leave(KErrInUse);
}
iTransientWriteEndPoint = &aWriter;
CleanupNullPointerPushL((TAny**)&iTransientWriteEndPoint);
TInt i = 0;
TRAPD(err,
for (i=0; i<iWriterProxies.Count(); ++i)
{
iTransientWriteEndPoint->IowepAttachL(*iWriterProxies[i]);
}
);
if (err)
{
// deatch the writers the we successfully attached before failure
for (TInt j=0; j<i; ++j)
{
iWriterProxies[j]->TransientWriterDetach(*iTransientWriteEndPoint);
}
User::Leave(err);
}
CleanupStack::Pop();
iWriteEndPointDetachOnClose = aDetachOnClose;
TRAP_IGNORE(iTransientWriteEndPoint->IowepSetTitleL(iTitleSetter));
for (TInt i=0; i<iWriterProxies.Count(); ++i)
{
iWriterProxies[i]->TransientWriterAttached(*iTransientWriteEndPoint);
}
}
void CIoPersistentConsole::DetachTransientWriter()
{
if (!iTransientWriteEndPoint)
{
return;
}
MIoWriteEndPoint* detaching = iTransientWriteEndPoint;
iTransientWriteEndPoint = NULL;
for (TInt i=0; i<iWriterProxies.Count(); ++i)
{
iWriterProxies[i]->TransientWriterDetach(*detaching);
}
iWriteEndPointDetachOnClose = NULL;
SendWriteDetachNotifications();
}
const MIoWriteEndPoint* CIoPersistentConsole::TransientWriter() const
{
return iTransientWriteEndPoint;
}
MIoWriteEndPoint* CIoPersistentConsole::TransientWriter()
{
return iTransientWriteEndPoint;
}
void CIoPersistentConsole::NotifyReadDetachL(const RMsg& aMessage)
{
if ((iReaderProxies.Count()==0) || !iTransientReadEndPoint)
{
Complete(aMessage, KErrNone);
}
else
{
iReadDetachNotifications.AppendL(aMessage);
}
}
void CIoPersistentConsole::CancelNotifyReadDetach(TRequestStatus* aClientStatus)
{
for (TInt i=0; i<iReadDetachNotifications.Count(); ++i)
{
if (iReadDetachNotifications[i].ClientStatus() == aClientStatus)
{
Complete(iReadDetachNotifications[i], KErrCancel);
iReadDetachNotifications.Remove(i);
return;
}
}
}
void CIoPersistentConsole::NotifyWriteDetachL(const RMsg& aMessage)
{
if ((iWriterProxies.Count()==0) || !iTransientWriteEndPoint)
{
Complete(aMessage, KErrNone);
}
else
{
iWriteDetachNotifications.AppendL(aMessage);
}
}
void CIoPersistentConsole::CancelNotifyWriteDetach(TRequestStatus* aClientStatus)
{
for (TInt i=0; i<iWriteDetachNotifications.Count(); ++i)
{
if (iWriteDetachNotifications[i].ClientStatus() == aClientStatus)
{
Complete(iWriteDetachNotifications[i], KErrCancel);
iWriteDetachNotifications.Remove(i);
return;
}
}
}
TName CIoPersistentConsole::TransientReaderName()
{
if (iTransientReadEndPoint)
{
return iTransientReadEndPoint->IoepName();
}
else
{
return KNullDesC();
}
}
TName CIoPersistentConsole::TransientWriterName()
{
if (iTransientWriteEndPoint)
{
return iTransientWriteEndPoint->IoepName();
}
else
{
return KNullDesC();
}
}
TThreadId CIoPersistentConsole::Creator()
{
return iCreator.Id();
}
TName CIoPersistentConsole::Name() const
{
return iName;
}
TBool CIoPersistentConsole::IsType(RIoHandle::TType aType) const
{
if (aType == RIoHandle::EPersistentConsole)
{
return ETrue;
}
else
{
return CIoConsole::IsType(aType);
}
}
void CIoPersistentConsole::SessionClosed(const CIoSession& aSession)
{
if (&aSession == iReadEndPointDetachOnClose)
{
DetachTransientReader();
}
if (&aSession == iWriteEndPointDetachOnClose)
{
DetachTransientWriter();
}
}
void CIoPersistentConsole::ClosedBy(const CIoSession& aSession)
{
SessionClosed(aSession);
}
void CIoPersistentConsole::SendReadDetachNotifications()
{
for (TInt i=0; i<iReadDetachNotifications.Count(); ++i)
{
Complete(iReadDetachNotifications[i], KErrNone);
}
iReadDetachNotifications.Reset();
}
void CIoPersistentConsole::SendWriteDetachNotifications()
{
for (TInt i=0; i<iWriteDetachNotifications.Count(); ++i)
{
Complete(iWriteDetachNotifications[i], KErrNone);
}
iWriteDetachNotifications.Reset();
}
//______________________________________________________________________________
// MIoReadEndPoint implementation - to handle reads from persistent side
TInt CIoPersistentConsole::HandleReaderAttached(MIoReader& aReader)
{
TIoReaderProxy* proxy = new TIoReaderProxy(aReader, *this);
TInt err = proxy ? KErrNone : KErrNoMemory;
if (err==KErrNone)
{
err = iReaderProxies.Append(proxy);
}
if ((err == KErrNone) && iTransientReadEndPoint)
{
TRAP(err, iTransientReadEndPoint->IorepAttachL(*proxy, RIoEndPoint::EBackground));
}
if (err != KErrNone)
{
TInt pos = ReaderProxyIndex(proxy);
if (pos!=KErrNotFound)
{
iReaderProxies.Remove(pos);
}
delete proxy;
}
return err;
}
void CIoPersistentConsole::HandleReaderDetached(MIoReader& aReader)
{
TInt pos = ReaderProxyIndex(&aReader);
if (pos!=KErrNotFound)
{
if (iTransientReadEndPoint)
{
iTransientReadEndPoint->IorepDetach(*iReaderProxies[pos]);
}
delete iReaderProxies[pos];
iReaderProxies.Remove(pos);
if (iReaderProxies.Count()==0)
{
SendReadDetachNotifications();
}
}
}
void CIoPersistentConsole::HandleForegroundReaderChanged()
{
if (iTransientReadEndPoint)
{
CIoEndPoint::HandleForegroundReaderChanged();
}
else
{
ForegroundReaderChanged();
}
}
void CIoPersistentConsole::ForegroundReaderChanged()
{
MIoReader* fgReader = AttachedReader();
if (iTransientReadEndPoint && fgReader)
{
TInt fgPos = ReaderProxyIndex(fgReader);
ASSERT(fgPos != KErrNotFound);
TRAPD(err, iTransientReadEndPoint->IorepSetForegroundReaderL(*iReaderProxies[fgPos]));
__ASSERT_ALWAYS(err == KErrNone, User::Invariant());
// this would only fail if this endpoints list of readers differs from the transient
// endpoints list; the two should always be kept in sync.
}
}
TInt CIoPersistentConsole::ReaderProxyIndex(MIoReader* aReader) const
{
for (TInt i=0; i<iReaderProxies.Count(); ++i)
{
if (&iReaderProxies[i]->ClientReader() == aReader)
{
return i;
}
}
return KErrNotFound;
}
void CIoPersistentConsole::IorepReadL(MIoReader& aReader)
{
TInt pos = ReaderProxyIndex(&aReader);
ASSERT(pos!=KErrNotFound);
iReaderProxies[pos]->ReadL(iTransientReadEndPoint);
}
void CIoPersistentConsole::IorepReadKeyL(MIoReader& aReader)
{
TInt pos = ReaderProxyIndex(&aReader);
ASSERT(pos!=KErrNotFound);
iReaderProxies[pos]->ReadKeyL(iTransientReadEndPoint);
}
void CIoPersistentConsole::IorepSetConsoleModeL(RIoReadWriteHandle::TMode aMode, MIoReader& aReader)
{
iPersistentConsoleMode = aMode;
GetReaderProxy(&aReader).SetConsoleModeL(iTransientReadEndPoint, aMode);
}
//______________________________________________________________________________
// MIoWriteEndPoint implementation - to handles writes from persistent side
TInt CIoPersistentConsole::HandleWriterAttached(MIoWriter& aWriter)
{
// call from CIoEndPoint
TIoWriterProxy* proxy = new TIoWriterProxy(aWriter, *this);
TInt err = proxy ? KErrNone : KErrNoMemory;
if (err==KErrNone)
{
err = iWriterProxies.Append(proxy);
}
if ((err == KErrNone) && iTransientWriteEndPoint)
{
TRAP(err, iTransientWriteEndPoint->IowepAttachL(*proxy));
}
if (err != KErrNone)
{
TInt pos = WriterProxyIndex(proxy);
if (pos!=KErrNotFound)
{
iWriterProxies.Remove(pos);
}
delete proxy;
}
return err;
}
void CIoPersistentConsole::HandleWriterDetached(MIoWriter& aWriter)
{
TInt pos = WriterProxyIndex(&aWriter);
if (pos!=KErrNotFound)
{
if (iTransientWriteEndPoint)
{
iWriterProxies[pos]->TransientWriterDetach(*iTransientWriteEndPoint);
}
delete iWriterProxies[pos];
iWriterProxies.Remove(pos);
if (iWriterProxies.Count()==0)
{
SendWriteDetachNotifications();
}
}
}
TInt CIoPersistentConsole::WriterProxyIndex(MIoWriter* aWriter) const
{
for (TInt i=0; i<iWriterProxies.Count(); ++i)
{
if (&iWriterProxies[i]->ClientWriter() == aWriter)
{
return i;
}
}
return KErrNotFound;
}
CIoPersistentConsole::TIoWriterProxy& CIoPersistentConsole::GetWriterProxy(MIoWriter* aWriter) const
{
TInt pos = WriterProxyIndex(aWriter);
ASSERT(pos!=KErrNotFound);
return *iWriterProxies[pos];
}
CIoPersistentConsole::TIoReaderProxy& CIoPersistentConsole::GetReaderProxy(MIoReader* aWriter) const
{
TInt pos = ReaderProxyIndex(aWriter);
ASSERT(pos!=KErrNotFound);
return *iReaderProxies[pos];
}
void CIoPersistentConsole::IowepWriteL(MIoWriter& aWriter)
{
TInt pos = WriterProxyIndex(&aWriter);
ASSERT(pos!=KErrNotFound);
iWriterProxies[pos]->WriteL(iTransientWriteEndPoint);
// move the proxy to the end of the array so that we service the writes
// in the correct order when we get a write end point, or when the end
// point goes away and comes back
TIoWriterProxy* proxy(iWriterProxies[pos]);
iWriterProxies.Remove(pos);
iWriterProxies.Append(proxy);
}
void CIoPersistentConsole::IowepWriteCancel(MIoWriter& aWriter)
{
TInt pos = WriterProxyIndex(&aWriter);
ASSERT(pos!=KErrNotFound);
iWriterProxies[pos]->WriteCancel(iTransientWriteEndPoint);
}
void CIoPersistentConsole::IowepCursorPosL(MIoWriter& aWriter) const
{
GetWriterProxy(&aWriter).GetCursorPosL(iTransientWriteEndPoint);
}
void CIoPersistentConsole::IowepSetCursorPosAbsL(const TPoint& aPoint, MIoWriter& aWriter)
{
GetWriterProxy(&aWriter).SetCursorPosAbsL(aPoint, iTransientWriteEndPoint);
}
void CIoPersistentConsole::IowepSetCursorPosRelL(const TPoint& aPoint, MIoWriter& aWriter)
{
GetWriterProxy(&aWriter).SetCursorPosRelL(aPoint, iTransientWriteEndPoint);
}
void CIoPersistentConsole::IowepSetCursorHeightL(TInt aPercentage, MIoWriter& aWriter)
{
GetWriterProxy(&aWriter).SetCursorHeightL(aPercentage, iTransientWriteEndPoint);
// TODO cache cursor height
}
void CIoPersistentConsole::IowepSetTitleL(MIoWriter& aWriter)
{
delete iTitle;
iTitle = NULL;
TRAP_IGNORE(iTitle = aWriter.IowTitleLC(); CleanupStack::Pop(iTitle)); // not much we can do if this fails
GetWriterProxy(&aWriter).SetTitleL(iTransientWriteEndPoint);
}
void CIoPersistentConsole::IowepClearScreenL(MIoWriter& aWriter)
{
GetWriterProxy(&aWriter).ClearScreenL(iTransientWriteEndPoint);
}
void CIoPersistentConsole::IowepClearToEndOfLineL(MIoWriter& aWriter)
{
GetWriterProxy(&aWriter).ClearToEndOfLineL(iTransientWriteEndPoint);
}
void CIoPersistentConsole::IowepScreenSizeL(MIoWriter& aWriter) const
{
GetWriterProxy(&aWriter).GetScreenSizeL(iTransientWriteEndPoint);
}
void CIoPersistentConsole::IowepSetAttributesL(TUint aAttributes, ConsoleAttributes::TColor aForegroundColor, ConsoleAttributes::TColor aBackgroundColor, MIoWriter& aWriter)
{
GetWriterProxy(&aWriter).SetAttributesL(aAttributes, aForegroundColor, aBackgroundColor, iTransientWriteEndPoint);
}
CIoPersistentConsole::CIoPersistentConsole(CIoServer& aServer)
: CIoConsole(aServer.Config()), iServer(aServer), iTitleSetter(iTitle)
{
}
CIoPersistentConsole::~CIoPersistentConsole()
{
iServer.PersistentConsoleRemove(iName, *this);
SendReadDetachNotifications();
iReadDetachNotifications.Close();
SendWriteDetachNotifications();
iWriteDetachNotifications.Close();
delete iTitle;
iWriterProxies.ResetAndDestroy();
iReaderProxies.ResetAndDestroy();
iCreator.Close();
}
_LIT(KPersistentConsoleImplementation, "<persistent console>");
void CIoPersistentConsole::ConstructL(const TDesC& aName, const TDesC& aTitle, const RMsg& aMessage)
{
LOG(CIoLog::Printf(_L("Persistent console %S @ 0x%08x created"), &aName, this));
iName = aName.Left(KMaxName);
iServer.PersistentConsoleAddL(iName, *this);
iImplementation = KPersistentConsoleImplementation().AllocL();
iTitle = aTitle.AllocL();
aMessage.ClientL(iCreator);
}
//______________________________________________________________________________
// TIoWriterProxy
// MIoWriter proxy to service write requests from the transient side
CIoPersistentConsole::TIoWriterProxy::TIoWriterProxy(MIoWriter& aWriter, CIoPersistentConsole& aOwner)
: iWriter(aWriter)
, iOwner(aOwner)
, iFlags(0)
{
}
TBool CIoPersistentConsole::TIoWriterProxy::GetFlag(TFlags aFlag)
{
return iFlags & aFlag;
}
void CIoPersistentConsole::TIoWriterProxy::SetFlag(TFlags aFlag)
{
iFlags |= aFlag;
}
void CIoPersistentConsole::TIoWriterProxy::ClearFlag(TFlags aFlag)
{
iFlags &= (~aFlag);
}
#define TRAP_OR(x, y) {TRAPD(err, x); if (err!=KErrNone) {y;} }
void CIoPersistentConsole::TIoWriterProxy::TransientWriterAttached(MIoWriteEndPoint& aEndPoint)
{
if (GetFlag(EWritePending))
{
TRAP_OR(aEndPoint.IowepWriteL(*this), IowComplete(err));
}
if (GetFlag(EGetCursorPosPending))
{
TRAP_OR(aEndPoint.IowepCursorPosL(*this), IowCursorPos(err, TPoint(0,0)));
}
if (GetFlag(ESetCursorPosAbsPending))
{
TRAP_OR(aEndPoint.IowepSetCursorPosAbsL(iSetCursPosAbsPoint, *this), IowSetCursorPosAbsComplete(err));
}
if (GetFlag(ESetCursorPosRelPending))
{
TRAP_OR(aEndPoint.IowepSetCursorPosRelL(iSetCursPosRelPoint, *this), IowSetCursorPosRelComplete(err));
}
if (GetFlag(ESetCursorHeightPending))
{
TRAP_OR(aEndPoint.IowepSetCursorHeightL(iSetCursorHeight, *this), IowSetCursorHeightComplete(err));
}
if (GetFlag(ESetTitlePending))
{
TRAP_OR(aEndPoint.IowepSetTitleL(*this), IowSetTitleComplete(err));
}
if (GetFlag(EClearScreenPending))
{
TRAP_OR(aEndPoint.IowepClearScreenL(*this), IowClearScreenComplete(err));
}
if (GetFlag(EClearToEndOfLinePending))
{
TRAP_OR(aEndPoint.IowepClearToEndOfLineL(*this), IowClearToEndOfLineComplete(err));
}
if (GetFlag(EGetScreenSizePending))
{
TRAP_OR(aEndPoint.IowepScreenSizeL(*this), IowScreenSize(err, TSize(0,0)));
}
if (GetFlag(ESetAttributesPending))
{
TRAP_OR(aEndPoint.IowepSetAttributesL(iAttributes, iForegroundColor, iBackgroundColor, *this), IowSetAttributesComplete(err));
}
}
void CIoPersistentConsole::TIoWriterProxy::TransientWriterDetach(MIoWriteEndPoint& aEndPoint)
{
if (GetFlag(EDetaching)) return;
if (GetFlag(EWritePending))
{
aEndPoint.IowepWriteCancel(*this);
// leave the write pending so it is serviced when we get a new transient end point
}
aEndPoint.IowepDetach(*this);
}
void CIoPersistentConsole::TIoWriterProxy::WriteL(MIoWriteEndPoint* aEndPoint)
{
SetFlag(EWritePending);
if (aEndPoint)
{
TRAPD(err, aEndPoint->IowepWriteL(*this));
if (err)
{
ClearFlag(EWritePending);
User::Leave(err);
}
}
}
void CIoPersistentConsole::TIoWriterProxy::WriteCancel(MIoWriteEndPoint* aEndPoint)
{
if (aEndPoint)
{
aEndPoint->IowepWriteCancel(*this);
}
ClearFlag(EWritePending);
}
MIoWriter& CIoPersistentConsole::TIoWriterProxy::ClientWriter() const
{
return iWriter;
}
void CIoPersistentConsole::TIoWriterProxy::GetCursorPosL(MIoWriteEndPoint* aEndPoint)
{
SetFlag(EGetCursorPosPending);
if (aEndPoint)
{
aEndPoint->IowepCursorPosL(*this);
}
}
void CIoPersistentConsole::TIoWriterProxy::SetCursorPosAbsL(const TPoint& aPos, MIoWriteEndPoint* aEndPoint)
{
SetFlag(ESetCursorPosAbsPending);
iSetCursPosAbsPoint = aPos;
if (aEndPoint)
{
aEndPoint->IowepSetCursorPosAbsL(iSetCursPosAbsPoint, *this);
}
}
void CIoPersistentConsole::TIoWriterProxy::SetCursorPosRelL(const TPoint& aPos, MIoWriteEndPoint* aEndPoint)
{
SetFlag(ESetCursorPosRelPending);
iSetCursPosRelPoint = aPos;
if (aEndPoint)
{
aEndPoint->IowepSetCursorPosRelL(iSetCursPosRelPoint, *this);
}
}
void CIoPersistentConsole::TIoWriterProxy::SetCursorHeightL(TInt aPercentage, MIoWriteEndPoint* aEndPoint)
{
SetFlag(ESetCursorHeightPending);
iSetCursorHeight = aPercentage;
if (aEndPoint)
{
aEndPoint->IowepSetCursorHeightL(iSetCursorHeight, *this);
}
}
void CIoPersistentConsole::TIoWriterProxy::SetTitleL(MIoWriteEndPoint* aEndPoint)
{
SetFlag(ESetTitlePending);
if (aEndPoint)
{
aEndPoint->IowepSetTitleL(*this);
}
}
void CIoPersistentConsole::TIoWriterProxy::ClearScreenL(MIoWriteEndPoint* aEndPoint)
{
SetFlag(EClearScreenPending);
if (aEndPoint)
{
aEndPoint->IowepClearScreenL(*this);
}
}
void CIoPersistentConsole::TIoWriterProxy::ClearToEndOfLineL(MIoWriteEndPoint* aEndPoint)
{
SetFlag(EClearToEndOfLinePending);
if (aEndPoint)
{
aEndPoint->IowepClearToEndOfLineL(*this);
}
}
void CIoPersistentConsole::TIoWriterProxy::GetScreenSizeL(MIoWriteEndPoint* aEndPoint)
{
SetFlag(EGetScreenSizePending);
if (aEndPoint)
{
aEndPoint->IowepScreenSizeL(*this);
}
}
void CIoPersistentConsole::TIoWriterProxy::SetAttributesL(TUint aAttributes, ConsoleAttributes::TColor aForegroundColor, ConsoleAttributes::TColor aBackgroundColor, MIoWriteEndPoint* aEndPoint)
{
SetFlag(ESetAttributesPending);
iAttributes = aAttributes;
iForegroundColor = aForegroundColor;
iBackgroundColor = aBackgroundColor;
if (aEndPoint)
{
aEndPoint->IowepSetAttributesL(iAttributes, iForegroundColor, iBackgroundColor, *this);
}
}
TInt CIoPersistentConsole::TIoWriterProxy::IowWriteLength() const
{
return iWriter.IowWriteLength();
}
TInt CIoPersistentConsole::TIoWriterProxy::IowWrite(TDes& aBuf)
{
return iWriter.IowWrite(aBuf);
}
void CIoPersistentConsole::TIoWriterProxy::IowComplete(TInt aError)
{
if (aError == KErrNone)
{
iWriter.IowComplete(KErrNone);
ClearFlag(EWritePending);
}
else
{
SetFlag(EDetaching);
iOwner.DetachTransientWriter();
ClearFlag(EDetaching);
}
}
TName CIoPersistentConsole::TIoWriterProxy::IowName()
{
TName name(iWriter.IowName());
if (name.Length() + KProxySuffix().Length() > name.MaxLength())
{
name.SetLength(name.MaxLength() - KProxySuffix().Length());
}
name.Append(KProxySuffix);
return name;
}
RIoReadWriteHandle::TMode CIoPersistentConsole::TIoWriterProxy::IorwMode() const
{
return iWriter.IorwMode();
}
void CIoPersistentConsole::TIoWriterProxy::IowCursorPos(TInt aError, TPoint aPos)
{
ClearFlag(EGetCursorPosPending);
iWriter.IowCursorPos(aError, aPos);
}
void CIoPersistentConsole::TIoWriterProxy::IowSetCursorPosAbsComplete(TInt aError)
{
ClearFlag(ESetCursorPosAbsPending);
iWriter.IowSetCursorPosAbsComplete(aError);
}
void CIoPersistentConsole::TIoWriterProxy::IowSetCursorPosRelComplete(TInt aError)
{
ClearFlag(ESetCursorPosRelPending);
iWriter.IowSetCursorPosRelComplete(aError);
}
void CIoPersistentConsole::TIoWriterProxy::IowSetCursorHeightComplete(TInt aError)
{
ClearFlag(ESetCursorHeightPending);
iWriter.IowSetCursorHeightComplete(aError);
}
void CIoPersistentConsole::TIoWriterProxy::IowSetTitleComplete(TInt aError)
{
ClearFlag(ESetTitlePending);
iWriter.IowSetTitleComplete(aError);
}
void CIoPersistentConsole::TIoWriterProxy::IowClearScreenComplete(TInt aError)
{
ClearFlag(EClearScreenPending);
iWriter.IowClearScreenComplete(aError);
}
void CIoPersistentConsole::TIoWriterProxy::IowClearToEndOfLineComplete(TInt aError)
{
ClearFlag(EClearToEndOfLinePending);
iWriter.IowClearToEndOfLineComplete(aError);
}
void CIoPersistentConsole::TIoWriterProxy::IowScreenSize(TInt aError, TSize aSize)
{
ClearFlag(EGetScreenSizePending);
iWriter.IowScreenSize(aError, aSize);
}
void CIoPersistentConsole::TIoWriterProxy::IowSetAttributesComplete(TInt aError)
{
ClearFlag(ESetAttributesPending);
iWriter.IowSetAttributesComplete(aError);
}
HBufC* CIoPersistentConsole::TIoWriterProxy::IowTitleLC()
{
return iWriter.IowTitleLC();
}
//______________________________________________________________________________
// TIoReaderProxy
// MIoReader proxy - to service read requests from transient side
CIoPersistentConsole::TIoReaderProxy::TIoReaderProxy(MIoReader& aReader, CIoPersistentConsole& aOwner)
: iReader(aReader), iOwner(aOwner), iDetaching(EFalse), iSetConsoleModePending(EFalse)
{
}
void CIoPersistentConsole::TIoReaderProxy::TransientReaderAttached(MIoReadEndPoint& aReader)
{
if (iReader.IorReadPending())
{
TRAPD(err, aReader.IorepReadL(*this));
if (err)
{
IorReadComplete(err);
}
}
if (iReader.IorReadKeyPending())
{
TRAPD(err, aReader.IorepReadKeyL(*this));
if (err)
{
IorReadKeyComplete(err, EKeyNull, 0);
}
}
if (iSetConsoleModePending)
{
TRAP_OR(aReader.IorepSetConsoleModeL(iSetConsoleMode, *this), IorSetConsoleModeComplete(err));
}
}
void CIoPersistentConsole::TIoReaderProxy::ReadL(MIoReadEndPoint* aEndPoint)
{
if (aEndPoint)
{
aEndPoint->IorepReadL(*this);
}
}
void CIoPersistentConsole::TIoReaderProxy::ReadKeyL(MIoReadEndPoint* aEndPoint)
{
if (aEndPoint)
{
aEndPoint->IorepReadKeyL(*this);
}
}
void CIoPersistentConsole::TIoReaderProxy::SetConsoleModeL(MIoReadEndPoint* aEndPoint, RIoReadWriteHandle::TMode aMode)
{
iSetConsoleModePending = ETrue;
iSetConsoleMode = aMode;
if (aEndPoint)
{
CleanupNullPointerPushL((TAny**)&iSetConsoleModePending);
aEndPoint->IorepSetConsoleModeL(iSetConsoleMode, *this);
CleanupStack::Pop();
}
}
MIoReader& CIoPersistentConsole::TIoReaderProxy::ClientReader() const
{
return iReader;
}
RIoReadWriteHandle::TMode CIoPersistentConsole::TIoReaderProxy::IorwMode() const
{
return iReader.IorwMode();
}
TBool CIoPersistentConsole::TIoReaderProxy::IorReadPending() const
{
return iReader.IorReadPending();
}
TBool CIoPersistentConsole::TIoReaderProxy::IorReadKeyPending() const
{
return iReader.IorReadKeyPending();
}
TDes& CIoPersistentConsole::TIoReaderProxy::IorReadBuf()
{
return iReader.IorReadBuf();
}
void CIoPersistentConsole::TIoReaderProxy::IorDataBuffered(TInt aLength)
{
iReader.IorDataBuffered(aLength);
}
TBool CIoPersistentConsole::TIoReaderProxy::IorDataIsBuffered() const
{
return iReader.IorDataIsBuffered();
}
TBool CIoPersistentConsole::TIoReaderProxy::IorIsKeyCaptured(TUint aKeyCode, TUint aModifiers) const
{
return iReader.IorIsKeyCaptured(aKeyCode, aModifiers);
}
TBool CIoPersistentConsole::TIoReaderProxy::IorAllKeysCaptured() const
{
return iReader.IorAllKeysCaptured();
}
void CIoPersistentConsole::TIoReaderProxy::IorReadComplete(TInt /*aError*/)
{
// indicates that the read end point will be providing no more data
// so detatch it
iDetaching = ETrue;
iOwner.DetachTransientReader();
iDetaching = EFalse;
}
void CIoPersistentConsole::TIoReaderProxy::IorReadKeyComplete(TInt aError, TUint aKeyCode, TUint aModifiers)
{
if (aError == KErrEof)
{
// indicates that the read end point will be providing no more data
// so detatch it
iOwner.DetachTransientReader();
}
else
{
iReader.IorReadKeyComplete(aError, aKeyCode, aModifiers);
}
}
TName CIoPersistentConsole::TIoReaderProxy::IorName()
{
TName name(iReader.IorName());
if (name.Length() + KProxySuffix().Length() > name.MaxLength())
{
name.SetLength(name.MaxLength() - KProxySuffix().Length());
}
name.Append(KProxySuffix);
return name;
}
void CIoPersistentConsole::TIoReaderProxy::IorReaderChange(TUint aChange)
{
iReader.IorReaderChange(aChange);
}
void CIoPersistentConsole::TIoReaderProxy::IorSetConsoleModeComplete(TInt aError)
{
iSetConsoleModePending = EFalse;
iReader.IorSetConsoleModeComplete(aError);
}
//______________________________________________________________________________
// TConsoleTitleSetter
TConsoleTitleSetter::TConsoleTitleSetter(HBufC*& aTitle)
: iTitle(aTitle)
{
}
TInt TConsoleTitleSetter::IowWriteLength() const
{
ASSERT(0);
return 0;
}
TInt TConsoleTitleSetter::IowWrite(TDes&)
{
ASSERT(0);
return 0;
}
void TConsoleTitleSetter::IowComplete(TInt)
{
ASSERT(0);
}
TName TConsoleTitleSetter::IowName()
{
ASSERT(0);
return TName();
}
RIoReadWriteHandle::TMode TConsoleTitleSetter::IorwMode() const
{
ASSERT(0);
return RIoReadWriteHandle::EText;
}
void TConsoleTitleSetter::IowCursorPos(TInt, TPoint)
{
ASSERT(0);
}
void TConsoleTitleSetter::IowSetCursorPosAbsComplete(TInt)
{
ASSERT(0);
}
void TConsoleTitleSetter::IowSetCursorPosRelComplete(TInt)
{
ASSERT(0);
}
void TConsoleTitleSetter::IowSetCursorHeightComplete(TInt)
{
ASSERT(0);
}
void TConsoleTitleSetter::IowSetTitleComplete(TInt)
{
}
void TConsoleTitleSetter::IowClearScreenComplete(TInt)
{
ASSERT(0);
}
void TConsoleTitleSetter::IowClearToEndOfLineComplete(TInt)
{
ASSERT(0);
}
void TConsoleTitleSetter::IowScreenSize(TInt, TSize)
{
ASSERT(0);
}
void TConsoleTitleSetter::IowSetAttributesComplete(TInt)
{
ASSERT(0);
}
HBufC* TConsoleTitleSetter::IowTitleLC()
{
return iTitle->AllocLC();
}