⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iomain.cpp

📁 在手机操作系统symbina上使用的一个脚本扩展语言的代码实现,可以参考用于自己的开发
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// IOMAIN.CPP
//
// Copyright (c) 1997-2002 Symbian Ltd. All rights reserved.

#include <oplr.h>
#include "iodef.h"
#include "iodev.h"
#include "oplutil.h"
#include <coemain.h>
#if !defined(__S80_DP2_0__)
#include <eikkeys.h>
#endif
#include <apgtask.h>
#include "clckupdt.h"
#include <fepbase.h>
#include <e32def.h>
#if defined(__UIQ__)
#include <quartzkeys.h>
#endif
#if defined(__SERIES60__)
#include <aknappui.h>
#include <coecntrl.h>
#endif

_LIT(KLitC, "C");
_LIT(KLitO, "O");
_LIT(KLitF, "F");
_LIT(KLitX, "X");
_LIT(KLitS, "S");
_LIT(KLitR, "R");
_LIT(KLitU, "U");
_LIT(KOplIOSystem,"Opl IO system");

const TInt KShelfLifeOfUnhandledUserEvents=10*1000000; // 10 seconds
const TInt KMaxNestedDialogDepth=16; // Max number of nested dialogs that the runtime can handle.
enum
	{
	EOplEventUnknown = 0x1400
	};

class TSingleEventSource : public MEventSource
	{
public:
	inline TSingleEventSource(TRequestStatus& aRequestStatus, TInt aPriority) :iRequestStatus(aRequestStatus), iPriority(aPriority) {}
private:
	// from MEventSource
	virtual void CancelRequest();
	virtual TRequestStatus& RequestStatus();
	virtual TInt Priority() const;
private:
	TRequestStatus& iRequestStatus;
	TInt iPriority;
	};

void TSingleEventSource::CancelRequest()
	// This function should never get called as objects of this class should 
	// only ever be the *only* event source being waited on (aUserEventsRequired must be 
	// EUserEventsNone, aArrayOfAdditionalEventSources must only contain this object)
	{
#ifdef _DEBUG
	User::Panic(KOplIOSystem,6);
#endif
	}

TRequestStatus& TSingleEventSource::RequestStatus()
	{
	return iRequestStatus;
	}

TInt TSingleEventSource::Priority() const
	{
	return iPriority;
	}

//
// Class TTimerEventSource
//
class TTimerEventSource : public MEventSource
	{
public:
	inline TTimerEventSource(RTimer& aActiveTimer, TRequestStatus& aRequestStatus, TInt aPriority) :iActiveTimer(aActiveTimer), iRequestStatus(aRequestStatus), iPriority(aPriority) {}
private:
	// from MEventSource
	virtual void CancelRequest();
	virtual TRequestStatus& RequestStatus();
	virtual TInt Priority() const;
private:
	RTimer& iActiveTimer;
	TRequestStatus& iRequestStatus;
	TInt iPriority;
	};

void TTimerEventSource::CancelRequest()
	{
	iActiveTimer.Cancel();
	}

TRequestStatus& TTimerEventSource::RequestStatus()
	{
	return iRequestStatus;
	}

TInt TTimerEventSource::Priority() const
	{
	return iPriority;
	}

//
// Class CEventQueue
//
class CEventQueue : public CBase, public CCoeFep::MKeyEventQueue
	{
public:
	static CEventQueue* NewL();
	virtual ~CEventQueue();
	inline TBool IsNotEmpty() const {return (iQueue.Count()>iNumberOfEventsInBackupRegion);}
	inline TBool BackupIsEmpty() const {return (iNumberOfEventsInBackupRegion==0);}
	inline void PeekNextEvent(TWsEvent& aEvent) const {aEvent=iQueue[iNumberOfEventsInBackupRegion];}
	inline void ConsumeNextEvent() {RemoveEventAdjustingNumberOfExpiringEvents(iNumberOfEventsInBackupRegion);}
	inline void PutNextEventInBackup() {++iNumberOfEventsInBackupRegion;}
	void RestoreAllEventsFromBackup();
	void PurgeAllNonKeyEvents();
	void PrepareToStartActiveScheduler();
	void NotifyActiveSchedulerStopped();
	TInt AppendEvent(const TWsEvent& aEvent);
	// from CCoeFep::MKeyEventQueue
	virtual void AppendKeyEventL(const TKeyEvent& aKeyEvent);
private:
	class CTimeOutTimer : private CTimer
		{
	public:
		static CTimeOutTimer* NewL(CEventQueue& aEventQueue);
		void Activate();
		void Deactivate();
	private:
		CTimeOutTimer(CEventQueue& aEventQueue);
		virtual void RunL();
	private:
		CEventQueue& iEventQueue;
		};
	friend class CTimeOutTimer;
private:
	CEventQueue();
	void ConstructL();
	void RemoveEventAdjustingNumberOfExpiringEvents(TInt aIndex);
	void PurgeAllExpiringEvents();
private:
	RArray<TWsEvent> iQueue;
	CTimeOutTimer* iTimeOutTimer;
	TInt iNumberOfEventsInBackupRegion;
	TInt iNumberOfExpiringEvents;
	};

CEventQueue* CEventQueue::NewL()
	{
	CEventQueue* eventQueue=new(ELeave) CEventQueue;
	CleanupStack::PushL(eventQueue);
	eventQueue->ConstructL();
	CleanupStack::Pop(); // eventQueue
	return eventQueue;
	}

CEventQueue::~CEventQueue()
	{
	iQueue.Close();
	delete iTimeOutTimer;
	}

void CEventQueue::RestoreAllEventsFromBackup()
	{
	CWsEventHandler::Signal(iNumberOfEventsInBackupRegion);
	iNumberOfEventsInBackupRegion=0;
	}

void CEventQueue::PurgeAllNonKeyEvents()
	{
	__ASSERT_DEBUG(BackupIsEmpty(), User::Panic(KOplIOSystem, 24));
	for (TInt i=iQueue.Count()-1; i>=0; --i)
		{
		if (iQueue[i].Type()!=EEventKey)
			{
			RemoveEventAdjustingNumberOfExpiringEvents(i);
			User::WaitForAnyRequest();	// returns straightaway as we're consuming the signal
										// associated with the event that has just been taken
										// out of iQueue
			}
		}
	}

void CEventQueue::PrepareToStartActiveScheduler()
	{
	// Empty the queue and stop the timer for purging old unhandled events
	iNumberOfExpiringEvents=iQueue.Count();
	PurgeAllExpiringEvents();
	iTimeOutTimer->Deactivate();
	}

void CEventQueue::NotifyActiveSchedulerStopped()
	{
	iTimeOutTimer->Activate();
	}

TInt CEventQueue::AppendEvent(const TWsEvent& aEvent)
	{
	const TInt error=iQueue.Append(aEvent);
	if (error==KErrNone)
		{
		CWsEventHandler::Signal(1);
		}
	return error;
	}

void CEventQueue::AppendKeyEventL(const TKeyEvent& aKeyEvent)
	{
	TWsEvent event;
	event.SetType(EEventKey);
	event.SetHandle(NULL);
	event.SetTimeNow();
	*event.Key()=aKeyEvent;
	User::LeaveIfError(AppendEvent(event));
	}

CEventQueue::CEventQueue()
	:iQueue(10),
	 iNumberOfEventsInBackupRegion(0),
	 iNumberOfExpiringEvents(0)
	{
	}

void CEventQueue::ConstructL()
	{
	iTimeOutTimer=CTimeOutTimer::NewL(*this);
	iTimeOutTimer->Activate();
	}

void CEventQueue::RemoveEventAdjustingNumberOfExpiringEvents(TInt aIndex)
	{
	iQueue.Remove(aIndex);
	if (aIndex<iNumberOfExpiringEvents)
		{
		--iNumberOfExpiringEvents;
		}
	}

void CEventQueue::PurgeAllExpiringEvents()
	{
	for (TInt i=iNumberOfExpiringEvents-1; i>=0; --i)
		{
		iQueue.Remove(i);
		if (i>=iNumberOfEventsInBackupRegion)
			{
			User::WaitForAnyRequest();	// returns straightaway as we're consuming the signal
										// associated with the event that has just been taken
										// out of iQueue
			}
		}
	iNumberOfExpiringEvents=iQueue.Count();
	}

//
// Class CEventQueue::CTimeOutTimer
//
CEventQueue::CTimeOutTimer* CEventQueue::CTimeOutTimer::NewL(CEventQueue& aEventQueue)
	{
	CTimeOutTimer* timeOutTimer=new(ELeave) CTimeOutTimer(aEventQueue);
	CleanupStack::PushL(timeOutTimer);
	timeOutTimer->ConstructL();
	CleanupStack::Pop(); // timeOutTimer
	return timeOutTimer;
	}

void CEventQueue::CTimeOutTimer::Activate()
	{
	After(TTimeIntervalMicroSeconds32(KShelfLifeOfUnhandledUserEvents));
	}

void CEventQueue::CTimeOutTimer::Deactivate()
	{
	Cancel();
	}

CEventQueue::CTimeOutTimer::CTimeOutTimer(CEventQueue& aEventQueue)
	:CTimer(EActivePriorityDefault),
	 iEventQueue(aEventQueue)
	{
	CActiveScheduler::Add(this);
	}

void CEventQueue::CTimeOutTimer::RunL()
	{
	iEventQueue.PurgeAllExpiringEvents();
	Activate();
	}

//
// Class CSignalBuffer
//
// This is a *very* non-standard active-derived class - it's used to temporarily
// buffer any signals from OPL asynchonous requests that complete whilst
// we're executing CActiveScheduler::Start (e.g. when displaying a dialog)
class CSignalBuffer : public CActive
	{
public:
	static CSignalBuffer* NewL();
	virtual ~CSignalBuffer();
	void StartBufferingAnyUnhandledSignals();
	void StopBufferingAndReplaceAnyBufferedSignals();
private:
	CSignalBuffer();
	virtual void DoCancel();
	virtual void RunL();
private:
	TInt iNumberOfBufferedSignals;
	};

CSignalBuffer* CSignalBuffer::NewL()
	{
	return new(ELeave) CSignalBuffer;
	}

CSignalBuffer::~CSignalBuffer()
	{
	Cancel();
	CWsEventHandler::Signal(iNumberOfBufferedSignals);
	}

void CSignalBuffer::StartBufferingAnyUnhandledSignals()
	{
	SetActive();
	}

void CSignalBuffer::StopBufferingAndReplaceAnyBufferedSignals()
	{
	// Stop buffering
	__ASSERT_ALWAYS(IsActive(), User::Panic(KOplIOSystem, 11));
	Cancel();
	// Restore any buffered signals
	CWsEventHandler::Signal(iNumberOfBufferedSignals);
	iNumberOfBufferedSignals=0;
	}

CSignalBuffer::CSignalBuffer()
	:CActive(KMinTInt),
	 iNumberOfBufferedSignals(0)
	{
	iStatus=KErrNone;
	CActiveScheduler::Add(this);
	}

void CSignalBuffer::DoCancel()
	{
	CWsEventHandler::Signal(1);	// Generate a signal for Cancel to consume to pretend that we're
								// a normal CActive-derived class (objects of this class actually
								// have *no* signal associated with them, even when IsActive(),
								// hence the need for this signal here)
	}

void CSignalBuffer::RunL()
	{
	++iNumberOfBufferedSignals;
	SetActive();
	}

//
// Class TArrayOfAdditionalEventSources
//
class TArrayOfAdditionalEventSources
	{
public:
	TArrayOfAdditionalEventSources(const TArray<MEventSource*>& aArrayOfAdditionalEventSources);
	inline TBool AtLeastOneHasCompletedAndBeenConsumed() const {return (iBitArrayOfCompletedAdditionalEventSourcesConsumed!=0);}
	const MEventSource* CompletedAdditionalEventSourceWithHighestPriority() const;
	void MarkAsConsumed(const MEventSource* aEventSource);	// to be passed what has been returned
															// by CompletedAdditionalEventSourceWithHighestPriority
	void CancelAll();
private:
	inline TBool HasNotBeenConsumed(TInt aIndex) const {return ((iBitArrayOfCompletedAdditionalEventSourcesConsumed&(1<<aIndex))==0);}
	inline void MarkAsConsumed(TInt aIndex) {__ASSERT_DEBUG((iArrayOfAdditionalEventSources[aIndex]->RequestStatus()!=KRequestPending) && HasNotBeenConsumed(aIndex), User::Panic(KOplIOSystem, 5)); iBitArrayOfCompletedAdditionalEventSourcesConsumed|=(1<<aIndex);}
private:
	const TArray<MEventSource*>& iArrayOfAdditionalEventSources;
	TUint iBitArrayOfCompletedAdditionalEventSourcesConsumed;
	};

TArrayOfAdditionalEventSources::TArrayOfAdditionalEventSources(const TArray<MEventSource*>& aArrayOfAdditionalEventSources)
	:iArrayOfAdditionalEventSources(aArrayOfAdditionalEventSources),
	 iBitArrayOfCompletedAdditionalEventSourcesConsumed(0)
	{
	__ASSERT_DEBUG(aArrayOfAdditionalEventSources.Count()<=(TInt)sizeof(TUint)*8, User::Panic(KOplIOSystem, 8));
	}

const MEventSource* TArrayOfAdditionalEventSources::CompletedAdditionalEventSourceWithHighestPriority() const
	{
	const MEventSource* completedAdditionalEventSourceWithHighestPriority=NULL;
	for (TInt i=iArrayOfAdditionalEventSources.Count()-1; i>=0; --i)
		{
		MEventSource& eventSource=*iArrayOfAdditionalEventSources[i];
		if ((eventSource.RequestStatus()!=KRequestPending) && HasNotBeenConsumed(i))
			{
			if ((completedAdditionalEventSourceWithHighestPriority==NULL) || (eventSource.Priority()>completedAdditionalEventSourceWithHighestPriority->Priority()))
				{
				completedAdditionalEventSourceWithHighestPriority=&eventSource;
				}
			}
		}
	return completedAdditionalEventSourceWithHighestPriority;
	}

void TArrayOfAdditionalEventSources::MarkAsConsumed(const MEventSource* aEventSource)
	{
	for (TInt i=iArrayOfAdditionalEventSources.Count()-1; ; --i)
		{
		__ASSERT_ALWAYS(i>=0, User::Panic(KOplIOSystem, 4));
		if (iArrayOfAdditionalEventSources[i]==aEventSource)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -