📄 iomain.cpp
字号:
{
MarkAsConsumed(i);
break;
}
}
}
void TArrayOfAdditionalEventSources::CancelAll()
{
for (TInt i=iArrayOfAdditionalEventSources.Count()-1; i>=0; --i)
{
if (HasNotBeenConsumed(i))
{
MEventSource& eventSource=*iArrayOfAdditionalEventSources[i];
eventSource.CancelRequest();
User::WaitForRequest(eventSource.RequestStatus()); // returns straightaway as
// eventSource's request has
// been cancelled
// Returns straightaway as we're consuming the signal associated with the
// cancelled event (however, if aStatPtr!=iStatPtr and both are non-NULL,
// this may hang indefinitely - this is the same behaviour as EPOC16 OPL,
// it basically means there's a bug in the OPL program)
}
}
}
const TInt KNoNestedDialogs=0;
class COplActiveScheduler : public CCoeScheduler
{
public:
enum TMode
{
EModeCone,
EModeOpl
};
public:
static COplActiveScheduler* NewL(CCoeEnv& aCoeEnv, COplRuntime& aRuntime);
virtual ~COplActiveScheduler();
void InstallOverConeActiveScheduler();
void ReinstallConeActiveScheduler();
#if defined(_DEBUG)
inline TBool IsInstalledOverConeActiveScheduler() const {return iInstalled;}
#endif
inline static void SetMode(TMode aMode) {OplActiveScheduler()->DoSetMode(aMode);}
// Cone mode nested dialog count
inline TInt IncConemodeNestCount(){return iConemodeNestCount++;}; //returns depth before push
inline TInt DecConemodeNestCount(){return --iConemodeNestCount;}; //returns depth after pop
private:
enum TSignature {ESignature=0x3ad6079e}; // a random number
private:
COplActiveScheduler(CCoeEnv& aCoeEnv, COplRuntime& aRuntime);
static COplActiveScheduler* OplActiveScheduler();
void DoSetMode(TMode aMode);
virtual void WaitForAnyRequest();
virtual void OnStarting();
virtual void OnStopping();
private:
CCoeEnv& iCoeEnv;
COplRuntime& iRuntime;
TSignature iSignature;
TInt iHeapCellLength;
CActiveScheduler* iConeActiveScheduler;
TMode iMode;
TBool iInstalled;
TInt iConemodeNestCount;
};
COplActiveScheduler* COplActiveScheduler::NewL(CCoeEnv& aCoeEnv, COplRuntime& aRuntime)
{
return new(ELeave) COplActiveScheduler(aCoeEnv, aRuntime);
}
COplActiveScheduler::~COplActiveScheduler()
{
__ASSERT_DEBUG(iConemodeNestCount==KNoNestedDialogs, User::Panic(KOplIOSystem, 40));
__ASSERT_DEBUG(!iInstalled, User::Panic(KOplIOSystem, 25));
}
void COplActiveScheduler::InstallOverConeActiveScheduler()
{
__ASSERT_DEBUG(!iInstalled, User::Panic(KOplIOSystem, 26));
iConeActiveScheduler=CActiveScheduler::Replace(this);
iInstalled=ETrue;
}
void COplActiveScheduler::ReinstallConeActiveScheduler()
{
__ASSERT_DEBUG(iInstalled, User::Panic(KOplIOSystem, 27));
#if defined(_DEBUG)
const CActiveScheduler* const activeScheduler=
#endif
CActiveScheduler::Replace(iConeActiveScheduler);
__ASSERT_DEBUG(activeScheduler==this, User::Panic(KOplIOSystem, 28));
iInstalled=EFalse;
}
#pragma warning (disable: 4355) // warning about "this" being used in base member initializer list
COplActiveScheduler::COplActiveScheduler(CCoeEnv& aCoeEnv, COplRuntime& aRuntime)
:CCoeScheduler(&aCoeEnv),
iCoeEnv(aCoeEnv),
iRuntime(aRuntime),
iSignature(ESignature),
iHeapCellLength(User::AllocLen(this)),
iConeActiveScheduler(NULL),
iMode(EModeCone), // forces DoSetMode below to call CCoeScheduler::CoeEnv()->Cancel()
iInstalled(EFalse),
iConemodeNestCount(0)
{
DoSetMode(EModeOpl);
}
#pragma warning (default: 4355)
COplActiveScheduler* COplActiveScheduler::OplActiveScheduler()
{
COplActiveScheduler* oplActiveScheduler=(COplActiveScheduler*)CActiveScheduler::Current();
__ASSERT_ALWAYS((oplActiveScheduler->iSignature==ESignature) && (oplActiveScheduler->iHeapCellLength==User::AllocLen(oplActiveScheduler)), User::Panic(KOplIOSystem, 18));
return oplActiveScheduler;
}
void COplActiveScheduler::DoSetMode(TMode aMode)
{
if ((iMode==EModeCone) && (aMode!=EModeCone))
{
iCoeEnv.Cancel();
}
iMode=aMode;
}
void COplActiveScheduler::WaitForAnyRequest()
{
switch (iMode)
{
case EModeOpl:
User::WaitForAnyRequest();
break;
case EModeCone:
CCoeScheduler::WaitForAnyRequest();
break;
default:
User::Panic(KOplIOSystem, 19);
break;
}
}
void COplActiveScheduler::OnStarting()
{
iRuntime.PrepareToStartActiveScheduler();
}
void COplActiveScheduler::OnStopping()
{
iRuntime.NotifyActiveSchedulerStopped();
}
//
// Class CPriorityKeyHandler
//
class CPriorityKeyHandler : CActive
{
public:
static CPriorityKeyHandler* NewL(RWsSession& aWindowServerSession, CWsEventHandler& aWsEventHandler);
virtual ~CPriorityKeyHandler();
inline TRequestStatus& Status() {return iStatus;}
inline void HandleCompletion() {DoHandleCompletion(EFalse);}
private:
CPriorityKeyHandler(RWsSession& aWindowServerSession, CWsEventHandler& aWsEventHandler);
void DoHandleCompletion(TBool aSetActive);
virtual void DoCancel();
virtual void RunL();
private:
RWsSession& iWindowServerSession;
CWsEventHandler& iWsEventHandler;
};
CPriorityKeyHandler* CPriorityKeyHandler::NewL(RWsSession& aWindowServerSession, CWsEventHandler& aWsEventHandler)
{
return new(ELeave) CPriorityKeyHandler(aWindowServerSession, aWsEventHandler);
}
CPriorityKeyHandler::~CPriorityKeyHandler()
{
Cancel();
}
CPriorityKeyHandler::CPriorityKeyHandler(RWsSession& aWindowServerSession, CWsEventHandler& aWsEventHandler)
:CActive(KMaxTInt),
iWindowServerSession(aWindowServerSession),
iWsEventHandler(aWsEventHandler)
{
CActiveScheduler::Add(this);
iWindowServerSession.PriorityKeyReady(&iStatus);
SetActive();
}
void CPriorityKeyHandler::DoHandleCompletion(TBool aSetActive)
{
__ASSERT_DEBUG(iStatus!=KRequestPending, User::Panic(KOplIOSystem, 7));
TWsPriorityKeyEvent event;
iWindowServerSession.GetPriorityKey(event);
iWindowServerSession.PriorityKeyReady(&iStatus);
// Next ASSERT: "logical-not" both sides before comparing for inequality
// to fold non-zero values
__ASSERT_DEBUG(!IsActive()!=!aSetActive, User::Panic(KOplIOSystem, 29));
if (aSetActive)
{
SetActive();
}
__ASSERT_DEBUG(IsActive(), User::Panic(KOplIOSystem, 30));
const TKeyEvent& key=*event.Key();
const TUint code=key.iCode;
const TUint mods=(key.iModifiers&EAllStdModifiers);
if ((code==EKeyEscape) && (mods==KKillKeyModifier))
{
// Terminate here - bail out!
#if defined(__SERIES60__)
CActiveScheduler::Stop();
// Not sure why OnStopping() isn't getting called...
// so do it manually...
TheRuntime()->NotifyActiveSchedulerStopped();
#endif
iWsEventHandler.Stop();
TheRuntime()->PrepareToExit();
delete TheRuntime(); // closes files etc.
User::Exit(0);
}
if (mods==KPauseKeyModifier)
{
switch (code)
{
case CTRL('s'):
iWsEventHandler.SetSuspended();
break;
case CTRL('q'):
iWsEventHandler.SetNotSuspended();
break;
}
}
}
void CPriorityKeyHandler::DoCancel()
{
iWindowServerSession.PriorityKeyReadyCancel();
}
void CPriorityKeyHandler::RunL()
{
DoHandleCompletion(ETrue);
}
//
// Class TIORequest
//
TIORequest::TIORequest(TAny* aPtr, TInt aPriority)
:iStatusPtr(aPtr),
iPriority(aPriority),
iHasHandledCompletion(EFalse)
{
}
void TIORequest::HandleCompletionIfNecessary()
{
if (!iHasHandledCompletion)
{
DoHandleCompletion();
iHasHandledCompletion=ETrue;
}
}
//
// Class TOplIORequest
//
#pragma warning (disable: 4310) // cast truncates constant
TOplIORequest::TOplIORequest(TOplReqStatus* aStatPtr, TInt aPriority)
:TIORequest(aStatPtr, aPriority)
{
OplUtil::PutWord((TOplReqStatus*)iStatusPtr,(TInt16)KOplErrFilePending);
}
#pragma warning (default: 4310)
void TOplIORequest::DoHandleCompletion()
{
DoParamsUpdate();
OplUtil::PutWord((TOplReqStatus*)iStatusPtr,OplUtil::MapError(iStatus.Int()));
}
void TOplIORequest::DoParamsUpdate()
{
}
//
// Class CIOCollection
//
void CIOCollection::ConstructL(COplRuntime* aRuntime,RWsSession& aWsSession)
{
iWsEventHandler=new(ELeave) CWsEventHandler(aWsSession,this);
iWsEventHandler->ConstructL(*aRuntime->ConEnv());
iRuntime=aRuntime;
}
TInt16 CIOCollection::NewObject(TInt16* aHandlePtr,TPtrC aPtr, TInt16 aMode)
{
TBuf<256> devName=aPtr;
return DoNewObject(aHandlePtr,devName,aMode);
}
TInt16 CIOCollection::NewObject(TInt16* aHandlePtr,TPtr& aPtr, TInt16 aMode)
//
// Specifically for use when creating a unique file name
//
{
TBuf<256> devName=aPtr;
TInt16 ret=DoNewObject(aHandlePtr,devName,aMode);
if (!ret)
aPtr=devName;
return ret;
}
TInt16 CIOCollection::DoNewObject(TInt16* aHandlePtr,TBuf<256>& aDevName, TInt16 aMode)
{
TOplIOType type=GetType(aDevName,aMode);
TInt index=FindSlot();
if (index==KErrGeneral)
return (TInt16)KErrNoMemory;
COplIO* obj;
switch (type)
{
case (ETimer):
{
obj=new(ELeave) COplIOTimer((TInt16)(index+KIOHandleBase));
break;
}
case (EComm):
{
obj=new(ELeave) COplIOComm((TInt16)(index+KIOHandleBase));
break;
}
case (EFileText):
{
obj=new(ELeave) COplIOFileText((TInt16)(index+KIOHandleBase));
break;
}
default:
{
obj=new(ELeave) COplIOFile((TInt16)(index+KIOHandleBase));
break;
}
}
TRAPD(err,obj->ConstructL(aDevName,aMode));
if (err)
delete obj;
else
{
iObjArray[index]=obj;
OplUtil::PutWord(aHandlePtr,(TInt16)(index+KIOHandleBase));
}
return OplUtil::MapError(err);
}
TInt CIOCollection::FindSlot()
{
for (TInt count=0;count<KMaxIOObjects;++count)
{
if (iObjArray[count]==NULL)
return count;
}
return KErrGeneral;
}
CIOCollection::TOplIOType CIOCollection::GetType(TBuf<256>& aDevName,TInt16 aMode)
{
if (aDevName.Locate(':')==3)
{
_LIT(KTIM,"TIM");
_LIT(KTTY,"TTY");
_LIT(KFIL,"FIL");
if (aDevName.Left(3).CompareF(KTIM)==KErrNone)
return ETimer;
if (aDevName.Left(3).CompareF(KTTY)==KErrNone)
return EComm;
// others in here
if (aDevName.Left(3).CompareF(KFIL)==KErrNone) // files don't need FIL:
aDevName.Delete(0,4);
}
if ((aMode&FMT_MASK)==FTEXT)
return EFileText;
return EFile;
}
void CIOCollection::RemoveObject(TInt16 aHandle)
{
aHandle-=KIOHandleBase;
if (aHandle<0 || aHandle>KMaxIOObjects)
User::Panic(KOplIOSystem,1);
delete iObjArray[aHandle];
iObjArray[aHandle]=NULL;
}
COplIO* CIOCollection::FindObjectL(TInt16 aHandle)
{
aHandle-=KIOHandleBase;
COplIO* obj=NULL;
if ((aHandle<0 || aHandle>KMaxIOObjects)||((obj=iObjArray[aHandle])==NULL))
User::Leave(KOplErrInvalidArgs);
return obj;
}
const TIORequest* CIOCollection::HandleAnyCompletedOplAsynchronousRequests()
// N.B. this function does *not* handle completed KEYA or GETEVENTA32 requests
{
const TIORequest* completedRequestWithHighestPriority=NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -